Aller au contenu
Administration Linux medium

Redirections et pipes sous Linux

50 min de lecture

Sous Linux, chaque commande produit du texte en sortie, et ce texte peut être envoyé ailleurs que l'écran. Vers un fichier, vers une autre commande, ou même vers le néant (/dev/null). Ce mécanisme s'appelle la redirection et c'est l'un des concepts les plus puissants du shell. Combiné avec le pipe (|), il permet d'enchaîner des commandes simples pour accomplir des tâches complexes.

  • Rediriger la sortie d'une commande vers un fichier avec > et >>
  • Distinguer sortie standard et sortie d'erreur
  • Enchaîner des commandes avec le pipe |
  • Masquer les erreurs avec /dev/null
  • Afficher et enregistrer en même temps avec tee
  • Éviter les quatre pièges qui font perdre des données ou mentent sur le résultat

Avant de rediriger quoi que ce soit, il faut comprendre que chaque commande utilise trois flux :

FluxNuméroNomRôle
Entrée standard0stdinCe que la commande lit (clavier par défaut)
Sortie standard1stdoutLe résultat normal (écran par défaut)
Sortie d'erreur2stderrLes messages d'erreur (écran par défaut)

Par défaut, stdout et stderr arrivent toutes les deux à l'écran. Les redirections permettent de les envoyer ailleurs.

Un processus écrit par défaut sur deux flux distincts, la sortie standard et la sortie d'erreur. La redirection détourne le premier vers un fichier ; le second continue de s'afficher à l'écran tant qu'on ne le traite pas séparément.

L'opérateur > envoie la sortie standard dans un fichier. Si le fichier existe, il est écrasé :

Fenêtre de terminal
ls /etc > liste.txt

Le fichier liste.txt contient maintenant la liste des fichiers de /etc. Rien ne s'affiche à l'écran.

Vérifiez :

Fenêtre de terminal
head -n 5 liste.txt

L'opérateur >> ajoute à la fin du fichier sans écraser le contenu existant :

Fenêtre de terminal
echo "--- Fin du rapport ---" >> liste.txt

Voici le piège qui coûte le plus cher aux débutants, et il n'est pas évident : c'est le shell qui prépare la redirection, avant de lancer la commande. Le fichier est donc vidé en premier, quoi qu'il arrive ensuite.

Fenêtre de terminal
echo "des données importantes" > rapport.txt
commande-qui-nexiste-pas > rapport.txt
bash: commande-qui-nexiste-pas: command not found

La commande n'a jamais tourné, elle sort en erreur (code 127), et pourtant :

Fenêtre de terminal
stat -c %s rapport.txt
0

Le fichier fait zéro octet. Une simple faute de frappe dans un nom de commande suffit donc à effacer un fichier existant. Le réflexe qui protège est d'écrire d'abord dans un fichier neuf, puis de remplacer l'ancien une fois le résultat vérifié.

Rediriger echo est un moyen simple de créer un petit fichier :

Fenêtre de terminal
echo "nameserver 1.1.1.1" > /tmp/resolv-test.conf

Chaque flux porte un descripteur numérique : 1 pour la sortie standard, 2 pour les erreurs. C'est ce numéro qu'on place devant le chevron pour choisir le flux à détourner, > seul étant un raccourci pour 1>.

Pour envoyer les messages d'erreur dans un fichier séparé :

Fenêtre de terminal
find /etc -name "*.conf" 2> erreurs.log

Les résultats normaux s'affichent à l'écran. Les erreurs « Permission denied » vont dans erreurs.log.

/dev/null est un fichier spécial qui avale tout ce qu'on lui envoie. C'est le « trou noir » de Linux :

Fenêtre de terminal
find / -name "sshd_config" 2>/dev/null

Les erreurs « Permission denied » disparaissent, seuls les résultats utiles s'affichent.

Pour envoyer tout (résultat + erreurs) dans un même fichier :

Fenêtre de terminal
find / -name "*.log" > tout.log 2>&1

2>&1 signifie « envoie le flux 2 (stderr) là où va le flux 1 (stdout) ».

L'ordre compte, et il n'est pas intuitif. Le shell lit les redirections de gauche à droite. Dans > tout.log 2>&1, stdout part d'abord dans le fichier, puis stderr est envoyé « au même endroit que stdout », donc dans le fichier aussi. Inversez, et vous n'obtenez plus la même chose :

Fenêtre de terminal
commande 2>&1 > tout.log

Ici, stderr est envoyé « là où va stdout » alors que stdout pointe encore vers l'écran. Il part donc à l'écran, et seul stdout finit dans le fichier. Mesuré sur une commande produisant 16 octets sur stdout et 59 sur stderr :

ÉcritureContenu du fichier
> tout.log 2>&175 octets, les deux flux
2>&1 > tout.log16 octets, stdout seul

Retenez la forme correcte : la redirection de stdout vient en premier.

Le pipe (|) connecte la sortie d'une commande à l'entrée de la suivante. C'est la base de la philosophie Unix : des outils simples combinés entre eux.

Fenêtre de terminal
ls /etc | head -n 5

ls liste les fichiers, le pipe envoie cette liste à head qui n'affiche que les 5 premières lignes.

Fenêtre de terminal
cat /etc/passwd | cut -d: -f1 | sort
  1. cat /etc/passwd, affiche le fichier
  2. cut -d: -f1, extrait le premier champ (le nom d'utilisateur) en utilisant : comme séparateur
  3. sort, trie par ordre alphabétique

Le résultat : la liste triée de tous les utilisateurs du système.

Fenêtre de terminal
ls /etc | wc -l

wc -l compte le nombre de lignes. Ici, le nombre de fichiers et répertoires dans /etc.

Fenêtre de terminal
ps aux | grep "sshd"

ps aux liste tous les processus, grep ne garde que ceux contenant « sshd ».

Dès que vous mettrez un pipe dans un script, ce détail vous rattrapera : le code de retour d'un tube est celui de sa dernière commande, pas celui de la première qui a échoué.

Fenêtre de terminal
commande-absente | wc -l
echo $?
0

commande-absente n'existe pas, mais wc -l a compté zéro ligne sans se plaindre, et c'est son code qui ressort. Un script qui teste $? conclut que tout s'est bien passé.

Bash garde pourtant la trace de chaque maillon dans le tableau PIPESTATUS :

Fenêtre de terminal
commande-absente | wc -l
echo "${PIPESTATUS[@]}"
127 0

Le 127 est bien là. Dans un script, le plus simple est de demander au shell de propager l'échec avec set -o pipefail, qui fait alors ressortir 127.

Par défaut, une redirection > envoie tout dans le fichier et rien à l'écran. Si vous voulez les deux :

Fenêtre de terminal
ls /etc | tee liste.txt

Le résultat s'affiche à l'écran et est enregistré dans liste.txt.

Pour ajouter au fichier au lieu d'écraser :

Fenêtre de terminal
ls /var | tee -a liste.txt
OpérateurRôleExemple
>Redirige stdout vers un fichier (écrase)ls > fichier.txt
>>Redirige stdout vers un fichier (ajoute)echo "fin" >> fichier.txt
2>Redirige stderr vers un fichierfind / -name x 2> err.log
2>/dev/nullIgnore les erreursfind / -name x 2>/dev/null
> f 2>&1Redirige stdout + stderrcmd > tout.log 2>&1
|Pipe : sortie d'une commande → entrée de la suivantels | head
teeAffiche et enregistre en même tempsls | tee fichier.txt
ProblèmeCause probableSolution
> a écrasé mon fichier> écrase toujoursUtiliser >> pour ajouter
Mon fichier est vide alors que la commande a échoué> vide le fichier avant d'exécuter la commandeÉcrire dans un fichier neuf, puis remplacer une fois le résultat vérifié
Le pipe ne donne rienLa première commande ne produit pas de sortieTester la première commande seule
Le tube « réussit » alors qu'une commande a échouéLe code de retour est celui de la dernière commandeLire ${PIPESTATUS[@]}, ou set -o pipefail dans un script
Une partie de la sortie manque dans le fichierÉcriture en > f 2> f : deux ouvertures, deux curseursUtiliser > f 2>&1
Permission denied avec >Pas le droit d'écrire dans le répertoireVoir l'encadré ci-dessous : sudo seul ne suffit pas
Les erreurs polluent le résultatstdout et stderr mélangés à l'écranAjouter 2>/dev/null
tee : commande introuvableTrès rare, paquet coreutils manquantsudo dnf install coreutils (RHEL/AlmaLinux) ou sudo apt install coreutils (Debian/Ubuntu)

La différence entre > et 2> ne devient un réflexe qu'une fois qu'on a produit soi-même les fichiers attendus. Ce lab vous demande de séparer stdout et stderr, de les fusionner quand c'est utile, puis d'enchaîner des commandes au pipe pour fabriquer des artefacts exacts, contrôlés à l'octet près.

Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

6 questions
6 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

  • > écrase, >> ajoute, c'est la différence la plus importante.
  • > vide le fichier avant d'exécuter la commande : une faute de frappe suffit à effacer un fichier existant.
  • | (pipe) est le ciment de la ligne de commande : il connecte les outils entre eux.
  • Le code de retour d'un tube est celui de la dernière commande : ${PIPESTATUS[@]} ou set -o pipefail pour voir les autres.
  • 2>/dev/null supprime les erreurs, indispensable avec find lancé sans sudo.
  • Pour fusionner les flux, > f 2>&1 et jamais > f 2> f, qui en détruit une partie. L'ordre compte.
  • sudo cmd > /fichier échoue toujours : la redirection est faite par votre shell. Utilisez | sudo tee.
  • tee est le compromis : afficher à l'écran et garder une trace dans un fichier.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn