Module 01 · Linux & Bash · Chapitre 3

3. Les flux de redirection

Dans le chapitre précédent, nous avons utilisé > et >> pour envoyer la sortie d’une commande dans un fichier. Nous allons maintenant comprendre ce mécanisme : sous Linux, une commande travaille avec plusieurs flux que Bash peut connecter à des fichiers ou à d’autres commandes.

Rappel — chapitre 2 : > remplace le contenu du fichier cible, tandis que >> ajoute à sa fin. Ici, nous généralisons cette notion aux trois flux standards.

3.1 Les trois flux standards

Lorsqu’un programme s’exécute dans le terminal, il dispose par défaut de trois flux. Chacun est identifié par un descripteur de fichier.

DescripteurNomRôle
0stdin — entrée standardDonnées reçues par la commande.
1stdout — sortie standardRésultat normal produit par la commande.
2stderr — erreur standardMessages d’erreur produits par la commande.

Par défaut, le clavier alimente l’entrée standard et le terminal affiche à la fois la sortie standard et l’erreur standard. La redirection permet de changer leur destination ou leur source.

3.2 Rediriger les sorties

3.2.1 Sortie standard : 1> et >

Le descripteur de stdout est 1. Ainsi, > est une écriture abrégée de 1>.

ls / > contenu
ls / 1> contenu

Ces deux commandes ont le même effet : la sortie normale de ls est écrite dans le fichier contenu.

3.2.2 Erreur standard : 2> et 2>>

Une commande qui tente de lire un fichier inexistant produit un message sur stderr :

cat no_file

Le descripteur de stderr étant 2, on peut rediriger ce message dans un fichier :

cat no_file 2> errors_file
head errors_file

Le message d’erreur n’apparaît alors plus dans le terminal : il se trouve dans errors_file. Comme pour stdout, 2> remplace le fichier et 2>> ajoute à sa fin.

3.2.3 Séparer stdout et stderr

Les deux sorties peuvent être envoyées vers deux fichiers différents. Dans l’exemple du cours, cat test enverra son résultat normal dans fic et ses erreurs dans log.

cat test 1>fic 2>log
cat fic
cat log

3.2.4 Regrouper stdout et stderr

La syntaxe 2>&1 signifie : « envoie le descripteur 2 vers la même destination que le descripteur 1 ».

ls -l > fic 2>&1

Ici, stdout est d’abord redirigée vers fic, puis stderr est redirigée vers la destination actuelle de stdout : les deux flux arrivent donc dans le même fichier.

Lecture de gauche à droite : > fic dirige stdout vers fic, puis 2>&1 dirige stderr vers l’endroit où stdout va déjà.

3.3 Rediriger l’entrée standard

Le descripteur de stdin est 0. La syntaxe <, équivalente à 0<, permet à une commande de lire son entrée depuis un fichier au lieu du clavier.

head < root_content

Dans cet exemple, head reçoit le contenu de root_content sur son entrée standard. Le résultat est ici équivalent à :

head root_content

3.3.1 Exemple avec un programme interactif

Le cours illustre mieux l’intérêt de stdin avec un petit programme Python qui attend normalement une saisie clavier :

name = input("Entrez votre nom\n")
print("Bonjour {} !".format(name))

Créez d’abord le fichier nom.py avec ce contenu, puis préparez une entrée dans un fichier :

echo Daniel > prenom

On peut alors alimenter automatiquement le programme :

python3 nom.py < prenom

Au lieu d’attendre que l’utilisateur tape son prénom, input() reçoit le contenu du fichier prenom via stdin.

3.4 Le pipe |

Le pipe | relie deux commandes : la sortie standard de la commande située à gauche devient l’entrée standard de celle située à droite.

ls / | grep bin

Le chemin logique est donc :

ls /  →  stdout  →  |  →  stdin  →  grep bin

ls / produit la liste du contenu de la racine. grep bin ne reçoit que cette sortie et conserve les lignes contenant bin.

Les pipes peuvent être enchaînés :

ls / | grep bin | head -n 1

La première commande produit les données, grep les filtre, puis head -n 1 ne conserve que la première ligne du résultat filtré.

À retenir : un pipe ne signifie pas simplement « exécuter ensuite ». Il transmet des données d’une commande à la suivante.

3.5 Enchaîner avec &&

&& enchaîne également des commandes, mais sans transmettre la sortie de l’une vers l’entrée de l’autre.

ls -l && python3 --version && mkdir Test

Les commandes sont exécutées de gauche à droite. La suivante n’est lancée que si la précédente s’est terminée avec succès. Le cours désigne ce comportement comme une évaluation paresseuse.

OpérateurLogique
|Transmet stdout de la commande de gauche vers stdin de la commande de droite.
&&Exécute la commande suivante seulement si la précédente réussit ; les données ne sont pas transmises.

3.6 Synthèse

SyntaxeEffet
< / 0<Utiliser un fichier comme entrée standard.
> / 1>Rediriger stdout en écrasant la destination.
>> / 1>>Rediriger stdout en ajoutant à la destination.
2>Rediriger stderr en écrasant la destination.
2>>Rediriger stderr en ajoutant à la destination.
2>&1Envoyer stderr vers la destination actuelle de stdout.
|Faire de stdout d’une commande le stdin de la suivante.
&&Exécuter la commande suivante seulement si la précédente réussit.
Bien. Ces aspects théoriques étant acquis. Les redirections deviennent surtout intéressantes lorsque plusieurs commandes sont assemblées : c’est l’une des bases de la puissance du shell.