La ligne de commande
Redirections, tubes, code de retour — ce qui fait la composition Unix.
La force du shell ne tient pas à ses commandes mais à la façon dont elles se composent. Chaque programme fait une chose, lit sur son entrée standard, écrit sur sa sortie standard — et le shell branche ces flux entre eux.
$ ss -ltn | awk 'NR>1 {print $4}' | cut -d: -f2 | sort -n | uniq
22
80
443Quatre outils qui ne se connaissent pas produisent la liste triée des ports en écoute. Aucun n'a été écrit pour les autres.
Trois flux, pas un
Un processus dispose de trois descripteurs standard, et les confondre est l'erreur la plus fréquente.
| Flux | Numéro | Rôle |
|---|---|---|
stdin | 0 | l'entrée |
stdout | 1 | le résultat |
stderr | 2 | les erreurs et diagnostics |
Un tube | ne transporte que stdout. C'est pourquoi commande | grep motif
laisse passer les erreurs à l'écran : elles empruntent stderr, que le tube
ignore. Pour les capturer aussi : 2>&1, à placer après la redirection de
stdout, l'ordre étant significatif.
commande > sortie.log 2>&1 # les deux dans le fichier
commande 2>&1 > sortie.log # stderr reste à l'écran — piège classiqueDans le second cas, 2>&1 duplique stderr vers là où pointe stdout à cet
instant — l'écran — avant que > ne redirige stdout.
Le code de retour gouverne l'enchaînement
Toute commande renvoie un entier : 0 pour la réussite, autre chose pour un
échec. C'est ce que lisent &&, || et if.
$ grep -q "^root:" /etc/passwd && echo "trouvé" || echo "absent"
trouvé$? contient le code de la dernière commande. Attention : dans un tube, c'est
celui de la dernière commande du tube, pas de celle qui a échoué —
false | true renvoie 0.
Les guillemets ne sont pas décoratifs
rm $fichier avec fichier="mes notes.txt" supprime mes et notes.txt. Le
shell découpe toute variable non protégée sur les espaces, puis développe les
jokers. La règle est simple : toujours "$fichier". C'est la première
cause de scripts qui fonctionnent en test et détruisent en production.
Écrire un script qui échoue au bon moment
Par défaut, un script continue après une erreur — et enchaîne sur des données absentes ou partielles. Trois options renversent ce comportement :
#!/usr/bin/env bash
set -euo pipefail-e arrête au premier échec, -u traite une variable non définie comme une
erreur — ce qui évite le fameux rm -rf "$PREFIXE/" où $PREFIXE est vide — et
-o pipefail fait échouer un tube dès qu'un de ses maillons échoue, corrigeant
le défaut vu plus haut.
Le piège classique
for f in $(ls *.txt) casse dès qu'un nom contient une espace, et se comporte
mal s'il n'y a aucun fichier. Le shell sait itérer directement sur les motifs :
for f in *.txt; do
[ -e "$f" ] || continue # aucun fichier : le motif reste littéral
traiter "$f"
doneRéponse unique
Pourquoi `commande 2>&1 > sortie.log` laisse-t-il les erreurs à l'écran ?
Indice · Les redirections sont évaluées de gauche à droite.
[ METTRE EN PRATIQUE ]
Composer, puis fiabiliser
3 étapes · 25 min · 110 XP
[ CETTE LEÇON DANS LES PARCOURS ]
- Fondamentauxétape 13 / 18suivant — Les permissions Unix →