CaenHackYouAcademy
Fondamentaux

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
443

Quatre 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.

FluxNuméroRôle
stdin0l'entrée
stdout1le résultat
stderr2les 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 classique

Dans 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/"$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"
done
VérificationQuestion 1 / 3

Ré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 ]

On this page