- stderr (sortie d’erreur standard) et stdout (sortie standard) sont réunis en un seul flux à l’aide d’une syntaxe de redirection
- Le chiffre 1 désigne stdout, 2 désigne stderr, et
& sert à indiquer une référence à un descripteur de fichier
2>&1 signifie « envoyer stderr vers la destination actuelle de stdout », et le résultat dépend de l’ordre des redirections
- Par exemple,
command >file 2>&1 envoie les deux flux dans le fichier, tandis que command 2>&1 >file laisse stderr sur la console
- Il s’agit d’une syntaxe de redirection essentielle, fréquemment utilisée dans Bash et les shells POSIX pour fusionner les sorties, enregistrer des logs et gérer des pipelines
Descripteurs de fichier et notions de base
- 0, 1, 2 désignent respectivement stdin, stdout, stderr
- Ils sont définis dans
/usr/include/unistd.h
#define STDIN_FILENO 0, #define STDOUT_FILENO 1, #define STDERR_FILENO 2
> indique une redirection de sortie, `` réécrit le fichier, et >> ajoute à la fin du fichier
- Le symbole
& indique qu’on référence un descripteur et non un nom de fichier
- Ainsi,
2>1 redirige vers un fichier nommé 1, tandis que 2>&1 duplique stderr vers stdout
Principe de fonctionnement de 2>&1
2> signifie qu’il faut rediriger stderr, et &1 référence le descripteur de fichier de stdout
- En conséquence, stderr est envoyé vers la même destination que stdout
- Exemples :
ls -ld /tmp /tnt >/dev/null 2>&1 → les deux sorties sont ignorées dans /dev/null
ls -ld /tmp /tnt 2>&1 >/dev/null → seul stderr reste affiché sur la console
- Les redirections sont traitées de gauche à droite, donc un ordre différent produit un résultat différent
Pourquoi l’ordre des redirections est important
command >file 2>&1
- stdout est d’abord envoyé dans le fichier, puis stderr est dupliqué vers stdout → les deux flux vont dans le fichier
command 2>&1 >file
- stderr est d’abord dupliqué vers le stdout courant (la console), puis seul stdout est redirigé vers le fichier → stderr continue de s’afficher sur la console
- Bash traite les redirections dans l’ordre, il faut donc faire attention à la séquence lors de l’écriture des commandes
Différents exemples de redirection
echo test >file.txt → redirige stdout vers le fichier
echo test 2>file.txt → redirige stderr vers le fichier
echo test 1>&2 → redirige stdout vers stderr
command &>file ou command >&file → redirige stdout et stderr vers le fichier (forme abrégée Bash)
command 2>&1 | tee -a file.txt → envoie les deux flux à la fois vers le fichier et le terminal
Usages avancés et fonctionnalités depuis Bash 4.0
- Depuis Bash 4.0, il est possible de séparer les sorties à l’aide de la substitution de processus
ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /')
- stdout et stderr sont envoyés chacun vers un filtre différent
|& est une forme abrégée de 2>&1 |, qui transmet les deux flux fusionnés dans un pipeline
- L’option
set -o noclobber empêche l’écrasement d’un fichier existant, avec possibilité d’exception via >|
Exemples d’usage en pratique
g++ main.cpp 2>&1 | head → permet de ne voir que le début de la sortie, y compris les erreurs de compilation
perl test.pl > debug.log 2>&1 → enregistre toute la sortie et les erreurs dans un fichier de log
foo 2>&1 | grep ERROR → recherche la chaîne ERROR à la fois dans stdout et stderr
docker logs container 2>&1 | grep "some log" → envoie l’ensemble des logs dans le pipeline
À retenir
2>&1 est une syntaxe POSIX standard qui duplique stderr vers stdout
- L’ordre des redirections détermine le résultat, il faut donc être vigilant lors de l’écriture des commandes
- Dans Bash,
&> permet de traiter les deux flux en même temps, et cette syntaxe est indispensable dans de nombreux scripts d’automatisation pour la gestion des logs, le traitement par pipeline et la fusion des erreurs
Aucun commentaire pour le moment.