From 8528384c8c1acad100bfe869bfe390a0f608fc16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9drix?= Date: Sat, 16 May 2026 18:00:58 +0200 Subject: [PATCH] =?UTF-8?q?draft:=20Variable=20`$$`=20=E2=80=94=20r=C3=A9c?= =?UTF-8?q?up=C3=A9rer=20le=20PID=20du=20shell?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../draft_overlay.json | 4 + .../draft_overlay.md | 122 ++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 b9f0369a-2823-4af4-819c-3a1fc0cf2b8c/draft_overlay.json create mode 100644 b9f0369a-2823-4af4-819c-3a1fc0cf2b8c/draft_overlay.md diff --git a/b9f0369a-2823-4af4-819c-3a1fc0cf2b8c/draft_overlay.json b/b9f0369a-2823-4af4-819c-3a1fc0cf2b8c/draft_overlay.json new file mode 100644 index 0000000..bcd14c0 --- /dev/null +++ b/b9f0369a-2823-4af4-819c-3a1fc0cf2b8c/draft_overlay.json @@ -0,0 +1,4 @@ +{ + "title": "Variable `$$` — récupérer le PID du shell", + "_updated_at": "2026-05-16 16:00:58" +} diff --git a/b9f0369a-2823-4af4-819c-3a1fc0cf2b8c/draft_overlay.md b/b9f0369a-2823-4af4-819c-3a1fc0cf2b8c/draft_overlay.md new file mode 100644 index 0000000..c1619da --- /dev/null +++ b/b9f0369a-2823-4af4-819c-3a1fc0cf2b8c/draft_overlay.md @@ -0,0 +1,122 @@ +# 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é. \ No newline at end of file