Dans le monde de l'interface en ligne de commande, les programmes interagissent souvent avec trois flux de données standard :
stdin) : là où un programme reçoit son entrée (généralement depuis le clavier).stdout) : là où un programme envoie sa sortie normale (généralement vers l'écran du terminal).stderr) : là où un programme envoie ses messages d'erreur (généralement vers l'écran du terminal).Souviens-toi qu'on les a présentés dans le chapitre Pipelines et listes de commandes.
On peut considérer les pipelines comme une forme de redirection : la sortie standard d'un programme est envoyée directement vers l'entrée standard d'un autre. Nous avons déjà vu les pipelines. Ce concept abordera la redirection depuis et vers des fichiers.
La redirection du shell est un mécanisme puissant qui permet de changer la destination de ces flux. Au lieu qu'un programme lise depuis le clavier ou écrive à l'écran, tu peux rediriger l'entrée depuis un fichier ou envoyer la sortie vers un fichier. Cela offre une grande souplesse et un bon contrôle sur la façon dont les programmes interagissent avec les données.
Voici les opérateurs de redirection les plus courants et ce qu'ils font :
> (redirection de la sortie)Rôle : rediriger la sortie standard (stdout) d'une commande vers un fichier.
Comportement :
Exemple :
# Sends the output of 'ls -l' to 'file_listing.txt'
ls -l > file_listing.txt
La redirection est effectuée avant l'exécution de la commande. Cela signifie que tu ne peux pas rediriger vers le même fichier que celui dont tu as besoin en lecture.
date > date.txt # populate the file with the current date
cat date.txt > date.txt # 'date.txt' is now empty!
Dans la seconde commande de l'exemple ci-dessus,
>> (ajout à la sortie)Rôle : ajouter la sortie standard (stdout) d'une commande à la fin d'un fichier.
Comportement :
Exemple :
# Adds "Another line" to the end of the file
echo "Another line" >> file_listing.txt
< (redirection de l'entrée)Rôle : rediriger l'entrée standard (stdin) d'une commande depuis un fichier.
Comportement : la commande lit son entrée depuis le fichier indiqué au lieu du clavier.
Exemple :
# 'tr' reads from 'lowercase.txt' and
# output is redirected to 'uppercase.txt'
tr 'a-z' 'A-Z' < lowercase.txt > uppercase.txt
2> (redirection des erreurs) :stderr) d'une commande vers un fichier.# Error message from 'rm' is sent to 'error_log.txt'
rm non_existent_file 2> error_log.txt
Tu peux ajouter l'erreur standard à la fin d'un fichier avec 2>>.
Il existe aussi des redirections qui permettent de fusionner à la fois stdin et stderr.
Voir le manuel pour plus de détails.
/dev/null/dev/null est un fichier spécial qui
On l'appelle parfois « le bitbucket ». Il est utile pour masquer la sortie ou les erreurs.
some_command > /dev/null # Discards stdout
some_command 2> /dev/null # Discards stderr
# Using /dev/null as input will prevent the command
# from reading data from the keyboard
some_command < /dev/null
On peut indiquer plusieurs redirections à la fois.
some_command < input.txt > output.txt 2> error.txt
Une redirection peut être copiée.
# send stderr to the same destination as stdout
some_command > output.txt 2>&1
Quand tu vois 2>&1, lis-le comme « redirige stderr vers ce vers quoi stdout pointe actuellement ».
Bash traite les instructions de redirection strictement de gauche à droite, ce qui signifie que tu peux faire :
# redirect stdout to 'output1.txt'
# redirect stderr to the same place
# then change stdout to 'output2.txt'
some_command > output1.txt 2>&1 > output2.txt
Dans le contexte de la programmation shell et des systèmes d'exploitation comme Linux/Unix, un descripteur de fichier (FD) est un entier positif ou nul qui sert d'identifiant ou de référence pour un fichier ouvert ou une ressource d'E/S (entrée/sortie). Vois-le comme une étiquette ou un numéro de référence que le système d'exploitation utilise pour garder la trace des fichiers ouverts et des flux de données.
Les nombres que tu vois à gauche des redirections sont des descripteurs de fichier.
Les trois premiers descripteurs de fichier sont attribués aux flux d'E/S standard :
On peut définir ou créer de nouveaux descripteurs de fichier avec la commande exec et les opérateurs de redirection.
# create FD 3 as a copy of stdout
exec 3>&1
# send stdout to a log file
exec > log.txt
# then redirect both stdout and file descriptor 3
echo "some debug message" >&3 # displayed in the terminal
some_command 2>&1 # stdout and stderr send to 'log.txt'
Cette technique paraît assez tortueuse, mais elle peut être très utile quand ton script est exécuté par un autre logiciel et que la sortie standard est récupérée automatiquement par ce logiciel.
La commande bats, utilisée pour exécuter les tests unitaires de ce parcours, fonctionne de cette manière : bats capture la sortie standard et la sortie d'erreur d'un test, mais les messages de débogage envoyés vers le descripteur 3 s'affichent dans le terminal.
Pourquoi la redirection est-elle utile ?
Les redirections du shell te donnent un contrôle fin sur la façon dont les programmes interagissent avec les données, ce qui te permet de construire des workflows complexes et de gérer efficacement l'information.