Dans un shell Unix, si je veux combiner stderr
et stdout
dans le flux stdout
pour une manipulation ultérieure, je peux ajouter ce qui suit à la fin de ma commande :
2>&1
Donc, si je veux utiliser head
sur la sortie de g++
, je peux faire quelque chose comme ceci :
g++ lots_of_errors 2>&1 | head
pour ne voir que les premières erreurs.
J'ai toujours du mal à m'en souvenir, et je dois constamment aller le chercher. C'est principalement parce que je ne comprends pas bien la syntaxe de cette astuce particulière.
Quelqu'un pourrait-il m'expliquer, caractère par caractère, ce que signifie "2>&1" ?
Le descripteur de fichier 1 est la sortie standard (stdout
).
Le descripteur de fichier 2 est l'erreur standard (stderr
).
Voici une façon de se souvenir de cette construction (bien qu'elle ne soit pas tout à fait exacte) : au début, 2>1
peut sembler être un bon moyen de rediriger stderr
vers stdout
. Cependant, il sera en fait interprété comme "rediriger stderr
vers un fichier nommé 1
". &
indique que ce qui suit est un descripteur de fichier et non un nom de fichier. Donc la construction devient : 2>&1
.
echo test > afile.txt
redirige stdout vers afile.txt
. C'est la même chose que de faire
echo test 1> afile.txt
Pour rediriger stderr, vous faites :
echo test 2> afile.txt
>&
est la syntaxe pour rediriger un flux vers un autre descripteur de fichier - 0 est stdin, 1 est stdout, et 2 est stderr.
Vous pouvez rediriger stdout vers stderr en faisant :
echo test 1>&2 # or echo test >&2
Ou vice versa :
echo test 2>&1
Donc, en résumé... 2>
redirige stderr vers un fichier (non spécifié), l'ajout de &1
redirige stderr vers stdout.
Les numéros font référence aux descripteurs de fichiers (fd).
stdin
stdout
.stderr
2>&1
redirige le fd 2 vers le 1.
Cela fonctionne pour n'importe quel nombre de descripteurs de fichiers si le programme les utilise.
Vous pouvez regarder dans /usr/include/unistd.h
si vous les oubliez :
/* Standard file descriptors. */
#define STDIN_FILENO 0 /* Standard input. */
#define STDOUT_FILENO 1 /* Standard output. */
#define STDERR_FILENO 2 /* Standard error output. */
Cela dit, j'ai écrit des outils en C qui utilisent des descripteurs de fichiers non standard pour la journalisation personnalisée, de sorte que vous ne la voyez pas à moins de la rediriger vers un fichier ou autre.