Files
abonnel-www/97a8f127-ee98-4b55-b565-5ff148fb8178/index.md
T

4.7 KiB

Variable $$ — récupérer le PID du shell

La variable spéciale $$ renvoie le PID (Process IDentifier) du shell courant, c'est-à-dire le numéro unique qu'attribue le système d'exploitation à chaque processus en cours d'exécution. Cette variable est particulièrement utile dans plusieurs situations courantes que nous allons détailler ci-dessous.

À quoi sert concrètement $$ ?

1. Générer des noms de fichiers temporaires uniques

Quand un script crée un fichier temporaire, il faut éviter les collisions si plusieurs instances du script tournent en même temps. Utiliser $$ dans le nom garantit l'unicité :

#!/bin/bash
# Création d'un fichier temporaire propre à cette exécution
TMPFILE="/tmp/monscript.$$.tmp"
echo "Données de travail" > "$TMPFILE"
echo "Fichier temporaire créé : $TMPFILE"
# Affichera par exemple : /tmp/monscript.17601.tmp

Si deux utilisateurs lancent le script simultanément, l'un aura /tmp/monscript.17601.tmp et l'autre /tmp/monscript.18422.tmp — pas de conflit possible.

2. Tracer un script dans les logs

Lorsqu'un script écrit dans un journal commun, préfixer chaque ligne par le PID permet de distinguer les exécutions parallèles :

#!/bin/bash
echo "[$$] Démarrage du script à $(date)" >> /var/log/monscript.log
echo "[$$] Traitement en cours..."        >> /var/log/monscript.log
echo "[$$] Fin du script"                 >> /var/log/monscript.log

Résultat dans le log :

[17601] Démarrage du script à Sat May 16 14:23:01 CEST 2026
[17601] Traitement en cours...
[17601] Fin du script

On peut ensuite filtrer une exécution particulière avec grep "\[17601\]" /var/log/monscript.log.

3. Créer un fichier de verrou (lock file)

Pour empêcher deux instances d'un script de tourner en même temps, on écrit son PID dans un fichier de verrou :

#!/bin/bash
LOCKFILE="/tmp/monscript.lock"

if [ -e "$LOCKFILE" ]; then
    echo "Script déjà en cours (PID $(cat $LOCKFILE)). Abandon."
    exit 1
fi

echo $$ > "$LOCKFILE"          # On enregistre notre PID
trap "rm -f $LOCKFILE" EXIT    # On nettoie à la sortie

echo "Travail en cours sous le PID $$..."
sleep 30

Particularité dans les sous-shells

$$ conserve toujours la valeur du shell parent, même lorsqu'elle est évaluée dans un sous-shell ( … ). C'est un piège classique : on pourrait croire que le sous-shell, étant un nouveau processus, aurait son propre PID via $$ — ce n'est pas le cas.

Pour obtenir le PID réel du processus Bash en cours d'exécution, Bash propose la variable $BASHPID.

Exemple comparatif

~ $ echo $$
17601
~ $ ( echo $$; echo $BASHPID )
17601
17634

Dans l'exemple ci-dessus :

  • $$ affiche 17601 dans les deux cas : c'est le PID du shell interactif d'origine, conservé même à l'intérieur des parenthèses.
  • $BASHPID affiche 17634 : c'est le PID du sous-shell réellement créé par les parenthèses.

Exemple plus parlant avec plusieurs niveaux de sous-shells

~ $ echo "Shell principal : \$\$=$$  \$BASHPID=$BASHPID"
Shell principal : $$=17601  $BASHPID=17601

~ $ ( echo "Sous-shell 1 : \$\$=$$  \$BASHPID=$BASHPID"
      ( echo "Sous-shell 2 (imbriqué) : \$\$=$$  \$BASHPID=$BASHPID" )
    )
Sous-shell 1 : $$=17601  $BASHPID=17634
Sous-shell 2 (imbriqué) : $$=17601  $BASHPID=17699

On voit clairement que :

  • $$ reste figé à 17601 (le shell de départ) dans tous les contextes.
  • $BASHPID change à chaque niveau d'imbrication : 17634 pour le premier sous-shell, 17699 pour le second.

Cas pratique : pourquoi cette distinction est importante

Imaginons qu'on veuille créer un fichier temporaire propre à un sous-shell :

~ $ ( TMP="/tmp/sub.$$.txt"
      echo "fichier = $TMP"
      TMP_REAL="/tmp/sub.$BASHPID.txt"
      echo "fichier réel = $TMP_REAL"
    )
fichier = /tmp/sub.17601.txt        # ⚠️ même nom que le shell parent !
fichier réel = /tmp/sub.17634.txt   # ✅ vraiment unique au sous-shell

Si plusieurs sous-shells utilisent $$, ils écrivent tous dans le même fichier — ce qui peut provoquer des écrasements de données. Avec $BASHPID, chaque sous-shell a son propre fichier.

À retenir

Variable Valeur retournée
$$ PID du shell de référence (le shell d'origine)
$BASHPID PID du processus Bash réellement en cours

Dans un shell standard sans sous-shell, les deux valeurs sont identiques. La différence n'apparaît qu'à l'intérieur de ( … ), et c'est précisément là qu'il faut savoir laquelle utiliser selon l'effet recherché.