Redirections et pipes
Rediriger les sorties vers un fichier et relier des commandes avec un pipe.
Objectifs
À la fin de cette leçon, vous saurez :
- expliquer les trois canaux standards d'une commande (stdin, stdout, stderr) ;
- rediriger la sortie d'une commande vers un fichier avec
>et>>, en connaissant la différence ; - relier plusieurs commandes en chaîne avec le pipe
|pour composer des traitements ; - enchaîner des commandes conditionnellement avec
&&,||et;.
🔗 Pour vous rafraîchir la mémoire : lecture de fichiers et aide (
cat,grep,man)
Préambule : les trois canaux d'une commande
Jusqu'ici, nous avons vu chaque commande comme une boîte qui « affiche des choses ». Affinons : tout programme Linux lancé depuis le shell dispose de trois canaux de communication, ouverts dès son démarrage :
stdin (entrée standard) canal n° 0 — par défaut : votre clavier
stdout (sortie standard) canal n° 1 — par défaut : l'écran du terminal
stderr (erreur standard) canal n° 2 — par défaut : l'écran du terminal
Le programme lit sur stdin, écrit ses résultats normaux sur stdout et ses messages d'erreur sur stderr. Pourquoi séparer résultats et erreurs alors que les deux s'affichent au même endroit ? Parce que ce sont deux usages différents :
- le résultat est une donnée qu'on veut souvent récupérer (l'enregistrer, la filtrer, la transmettre) ;
- le message d'erreur est un diagnostic pour l'humain, qu'on ne veut pas mélanger aux données.
Garder ces canaux séparés permet de traiter chacun comme on veut. C'est exactement ce que permettent les redirections.
Rediriger stdout vers un fichier
$ ls -la > liste.txt
$
Observation importante : rien ne s'est affiché. Le > a détourné stdout : le texte produit par ls -la est parti écrire dans liste.txt au lieu de venir à l'écran. Vérifions :
$ cat liste.txt
total 28
drwx------ 4 cours cours 4096 Jan 12 09:14 .
drwxr-xr-x 3 root root 4096 Jan 12 09:00 ..
-rw-r--r-- 1 cours cours 62 Jan 12 09:41 liste.txt
...
La lecture se fait ainsi : commande > fichier. Le fichier est créé s'il n'existe pas.
Différence cruciale entre > et >> : le simple > écrase tout contenu précédent ; le double >> (append) ajoute à la fin. Démonstration sans risque :
$ echo "première passe" > journal.txt
$ cat journal.txt
première passe
$ echo "deuxième passe" > journal.txt
$ cat journal.txt
deuxième passe ← la première ligne a disparu !
$ echo "troisième passe" >> journal.txt
$ cat journal.txt
deuxième passe
troisième passe ← ici, ajouté à la suite
(echo affiche simplement le texte qu'on lui passe — ici détourné vers un fichier.)
Ce piège de l'écrasement est réel : relancer une commande avec > efface silencieusement l'ancien fichier. Règle pratique : > quand on veut un résultat neuf, >> quand on accumule (journaux, historiques, rapports).
Rediriger stdin depuis un fichier
Symétriquement, < remplace le clavier par un fichier :
$ wc -l < demo.txt
6
wc -l (word count) compte normalement ce qu'on lui tape au clavier ; ici, il a lu demo.txt grâce à < et répondu : 6 lignes. Comparons avec la forme argument :
$ wc -l demo.txt
6 demo.txt
Les deux formes donnent le même compte, mais pas la même sortie : dans la seconde, wc connaît le nom du fichier puisqu'il l'a reçu en argument et l'affiche ; dans la première, il n'a reçu que du texte via son entrée standard. La différence paraît subtile aujourd'hui ; elle deviendra évidente avec les pipes, où il n'y a plus de nom de fichier du tout.
Le pipe : brancher deux commandes bout à bout
Le pipe | connecte le stdout d'une commande au stdin de la suivante. C'est le concept le plus puissant de cette leçon :
ls /usr/bin | grep zip
Déroulons le mécanisme :
ls /usr/binproduit la liste de tous les programmes installés — des centaines de lignes — sur son stdout ;- au lieu d'aller à l'écran, ce flux part directement dans le stdin de
grep zip; grepfiltre le flux ligne par ligne et n'affiche que celles contenant « zip » :bzip2 funzip gunzip gzip unzip zip zipinfo
L'analogie juste : c'est une chaîne de montage. Chaque commande fait une seule opération simple, mais le produit d'une station alimente la suivante. Et remarquez ce qui n'existe plus : aucun fichier intermédiaire, aucune étape manuelle — le flux circule en mémoire.
Composons trois stations pour sentir la puissance :
$ history | grep grep | wc -l
7
Lecture : prends mon historique, garde-en les lignes qui parlent de grep, compte-les. Trois outils spécialisés, une question résolue en une ligne, sans fichier temporaire. C'est toute la philosophie Unix : faire peu de choses, mais les faire bien, et les assembler.
Deux commandes compagnons utiles dans ces chaînes :
$ ls /usr/bin | sort | head -n 5 # trier, puis prendre le début
[
a2p
ac
accessdb
aclocal
sort trie les lignes reçues ; combinée à uniq -c (qui fusionne les lignes identiques en les comptant), elle donne des statistiques en une ligne. Vous verrez ces assemblages partout dans la vraie vie des serveurs.
Point de vigilance : le pipe ne transporte que stdout. Les messages d'erreur (stderr) le traversent comme si de rien n'était et continuent d'aller à l'écran. C'est voulu : on filtre les données, pas les diagnostics. (Rediriger stderr existe —
2>— mais attendez d'en avoir besoin.)
Enchaîner selon le succès : &&, || et ;
Dernière pièce : exécuter plusieurs commandes sur une même ligne, avec ou sans condition.
$ cd /tmp && touch test.txt
&& signifie : exécute la seconde seulement si la première a réussi. Ici, si cd /tmp échouait, aucun test.txt ne serait créé ailleurs par accident. C'est un garde-fou quotidien.
$ ls /dossier-inexistant || echo "échec de lecture"
ls: impossible d'accéder à '/dossier-inexistant' : Aucun fichier ou dossier de ce type
échec de lecture
|| exécute la seconde seulement si la première échoue — typique pour afficher un message ou prendre une action de secours.
$ date ; whoami
dim. 12 janv. 2026 09:55:12 CET
cours
; enchaîne inconditionnellement, quoi qu'il arrive.
Mais au fait : comment le shell sait-il qu'une commande a réussi ? Chaque commande rend à sa fin un nombre appelé code de retour : 0 = succès, autre = échec. && et || lisent ce code. Ce mécanisme, invisible ici, est si fondamental que le chapitre suivant commence par l'observer de nos propres yeux.
Exercice
- Redirigez la liste détaillée de
/homedansmaison.txt, puis affichez-la. - Ajoutez ensuite la liste détaillée de
/etcau même fichier, puis comptez ses lignes. - Avec exactement deux commandes reliées par un pipe, affichez seulement les 4 premières entrées de
/usr/bin. - Comptez combien de programmes de
/usr/bincontiennent la lettre « z ». - Sans ouvrir d'éditeur, ajoutez la ligne « Fait : vérifié » à la fin d'un fichier
carnet.txt— deux fois de suite — puis vérifiez le contenu. - Question de réflexion : pourquoi
echo "bonjour" > fichier-existant.txtest-il dangereux alors queecho "bonjour" >> fichier-existant.txtne l'est pas ?
Résumé
- Tout programme a trois canaux : stdin (0), stdout (1), stderr (2). Résultats et erreurs voyagent séparément.
>crée/écrase,>>ajoute ;<fournit l'entrée depuis un fichier.|branche stdout sur stdin : chaîne de montage de commandes simples (ls | grep x | wc -l).&&conditionne au succès,||à l'échec,;ne conditionne rien — le tout repose sur le code de retour, sujet du prochain chapitre.
Correction disponibleCherchez d’abord par vous-même.Voir la correction
Correction
Réponses détaillées
Exercice 1.
ls -la /home > maison.txt
cat maison.txt
Exercice 2.
$ ls -la /etc >> maison.txt
$ wc -l maison.txt
187 maison.txt (votre total variera)
Le point clé était >> : avec >, la liste /etc aurait remplacé celle de /home. On peut vérifier que le total dépasse la taille de chaque liste seule : le fichier contient bien les deux.
Exercice 3.
ls /usr/bin | head -n 4
Sans pipe, il aurait fallu lister tout puis lire en haut de l'écran ; avec, la machine fait le tri.
Exercice 4.
$ ls /usr/bin | grep z | wc -l
23 (valeur indicative)
Chaîne en trois stations : lister, filtrer, compter. Variante en une commande : ls /usr/bin | grep -c z.
Exercice 5.
$ echo "Fait : vérifié" >> carnet.txt
$ echo "Fait : vérifié" >> carnet.txt
$ cat carnet.txt
Fait : vérifié
Fait : vérifié
Si vous avez utilisé > la deuxième fois, cat n'a montré qu'une seule ligne : c'est précisément le piège de la question 6.
Exercice 6. > écrase le fichier existant sans demander ni prévenir : le contenu précédent est perdu irrémédiablement (pas de corbeille). >> ajoute à la fin : le contenu existant reste intact, même si le fichier n'existait pas encore (auquel cas il est créé). La dangerosité vient donc uniquement de la perte silencieuse possible avec >.