# 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é : ```bash #!/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 : ```bash #!/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 : ```bash #!/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 ```bash ~ $ 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 ```bash ~ $ 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 : ```bash ~ $ ( 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é.