draft: $$

This commit is contained in:
Cédrix
2026-05-16 18:04:15 +02:00
parent aa6a415bb7
commit c704a7c12e
3 changed files with 127 additions and 0 deletions
@@ -0,0 +1,4 @@
{
"title": "Variable `$$` — récupérer le PID du shell",
"_updated_at": "2026-05-16 16:04:15"
}
@@ -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é.
+1
View File
@@ -196,3 +196,4 @@
{"ts":"2026-05-16 15:47:47","url":"/informatique/linux/cfp/create-raid","ref":"","ua":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36"}
{"ts":"2026-05-16 15:48:58","url":"/informatique/linux/system/uefi","ref":"","ua":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36"}
{"ts":"2026-05-16 15:56:28","url":"/informatique/virtualisation/nat-forwarding","ref":"","ua":"Mozilla/5.0 (Macintosh; Intel Mac OS X 12.1; rv:125.0) Gecko/20100101 Firefox/125.0"}
{"ts":"2026-05-16 16:04:01","url":"/informatique/linux/commandes/dd","ref":"https://abonnel.fr/informatique/linux/commandes/dd","ua":"Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; SleepBot/1.0; +http://sleepbot.com/) Chrome/131.0.0.0 Safari/537.36"}