Dans un shell Unix, si je veux combiner stderr
et stdout
dans le stdout
flux 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
donc je ne peux voir que les premières erreurs.
J'ai toujours du mal à m'en souvenir, et je dois constamment chercher, et c'est principalement parce que je ne comprends pas bien la syntaxe de cette astuce particulière.
Quelqu'un peut-il diviser cela et expliquer ce que 2>&1
signifie caractère par caractère ?
2>&1
que 2> / dev / null ;-)|&
c'est un raccourci pour2>&1 |
si vous utilisez zsh. Je ne peux pas dire si cela s'applique à d'autres coquilles de type bourne ou si c'est une fonctionnalité uniquement zsh.Réponses:
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 entièrement exacte): au début, cela
2>1
peut sembler être un bon moyen de redirigerstderr
versstdout
. Cependant, il sera en fait interprété comme "redirigerstderr
vers un fichier nommé1
".&
indique que ce qui suit est un descripteur de fichier et non un nom de fichier. Ainsi , la construction devient:2>&1
.la source
&2>&1
?&
n'est interprété que comme signifiant "descripteur de fichier" dans le contexte des redirections. L'écriturecommand &2>&
est analysée commecommand &
et2>&1
, c'est-à-dire "exécutercommand
en arrière-plan, puis exécuter la commande2
et rediriger sa sortie standard vers sa sortie standard".2>'&1'
redirige stdout vers
afile.txt
. C'est la même chose que de fairePour rediriger stderr, vous faites:
>&
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:
Ou vice versa:
Donc, en bref ...
2>
redirige stderr vers un fichier (non spécifié), en ajoutant&1
redirige stderr vers stdout.la source
java ... 2&1 >> data.log
, j'ai vu un de mes collègues faire ça?cmd 2>&1 >> somefile.log
ajoutera stdout / stderr à un fichier - c'est fondamentalement la même que ci-dessus, avec>> file
à ajoutercmd 2>&1 >>file
ne redirige pas stderr vers le fichier, mais lecmd >> file 2>&1
fait. L'ordre est important. Dans le premier cas, stderr est redirigé vers la sortie standard du shell (éventuellement un tty si la commande est entrée de manière interactive), puis la sortie standard est dirigée vers le fichier. Dans le second cas, stdout est dirigé vers le fichier, puis stderr est dirigé vers le même endroit.0(or 1,2)>&0(or 1,2)
comme une option pour contrôler la sortie? C'estecho test >test.log 2>&1
pareilecho test 2>&1 >test.log
?Quelques astuces sur la redirection
Certaines particularités de syntaxe à ce sujet peuvent avoir des comportements importants. Il y a quelques petits échantillons sur les redirections,
STDERR
,STDOUT
et arguments commande .1 - Écraser ou ajouter?
Symbole
>
signifie redirection .>
signifie envoyer dans un fichier complet , écraser la cible si elle existe (voir lanoclobber
fonction bash au n ° 3 plus tard).>>
signifie envoyer en plus de s'ajouterait à la cible s'il existe.Dans tous les cas, le fichier serait créé s'il n'existait pas.
2 - La ligne de commande du shell dépend de l'ordre !!
Pour tester cela, nous avons besoin d' une commande simple qui enverra quelque chose sur les deux sorties :
(En supposant que vous n'ayez pas de répertoire nommé
/tnt
, bien sûr;). Eh bien, nous l'avons !!Voyons donc:
La dernière ligne de commande se décharge
STDERR
sur la console, et cela ne semble pas être le comportement attendu ... Mais ...Si vous souhaitez effectuer un post-filtrage sur une sortie, l'autre ou les deux:
Notez que la dernière ligne de commande de ce paragraphe est exactement la même que dans le paragraphe précédent, où j'ai écrit ne semble pas être le comportement attendu (donc, cela pourrait même être un comportement attendu).
Eh bien, il y a quelques astuces sur les redirections, pour effectuer différentes opérations sur les deux sorties :
Nota: le
&9
descripteur se produirait spontanément à cause de) 9>&2
.Addendum: nota! Avec la nouvelle version defrapper(
>4.0
) il y a une nouvelle fonctionnalité et une syntaxe plus sexy pour faire ce genre de choses:Et enfin pour un tel formatage de sortie en cascade:
Addendum: nota! Même nouvelle syntaxe, dans les deux sens:
Où
STDOUT
passer par un filtre spécifique,STDERR
à un autre et enfin les deux sorties fusionnées passent par un troisième filtre de commande.3 - Un mot sur l'
noclobber
option et la>|
syntaxeIl s'agit d' écraser :
Tout en
set -o noclobber
demandant à bash de ne pas écraser de fichier existant, la>|
syntaxe vous permet de passer par cette limitation:Le fichier est écrasé à chaque fois, enfin maintenant:
Passer avec
>|
:Désactiver cette option et / ou demander si elle est déjà définie.
4 - Dernière astuce et plus ...
Pour rediriger les deux sorties d'une commande donnée, nous voyons qu'une bonne syntaxe pourrait être:
pour ce cas particulier , il existe une syntaxe de raccourci:
&>
... ou>&
Nota: si elle
2>&1
existe,1>&2
est une syntaxe correcte aussi:4b- Maintenant, je vais vous laisser réfléchir sur:
4c- Si vous souhaitez plus d' informations
Vous pouvez lire le bon manuel en cliquant sur:
dans un frapper console ;-)
la source
J'ai trouvé ce brillant article sur la redirection: Tout sur les redirections
Redirige la sortie standard et l'erreur standard vers un fichier
Ce one-liner utilise l'
&>
opérateur pour rediriger les deux flux de sortie - stdout et stderr - de la commande vers le fichier. Il s'agit du raccourci de Bash pour rediriger rapidement les deux flux vers la même destination.Voici à quoi ressemble la table des descripteurs de fichiers après que Bash a redirigé les deux flux:
Comme vous pouvez le voir, stdout et stderr pointent maintenant vers
file
. Donc, tout ce qui est écrit sur stdout et stderr est écritfile
.Il existe plusieurs façons de rediriger les deux flux vers la même destination. Vous pouvez rediriger chaque flux l'un après l'autre:
Il s'agit d'un moyen beaucoup plus courant de rediriger les deux flux vers un fichier. La première stdout est redirigée vers le fichier, puis stderr est dupliqué pour être identique à la stdout. Donc, les deux flux finissent par pointer vers
file
.Lorsque Bash voit plusieurs redirections, il les traite de gauche à droite. Passons en revue les étapes et voyons comment cela se produit. Avant d'exécuter des commandes, la table des descripteurs de fichiers de Bash ressemble à ceci:
Maintenant, Bash traite le premier fichier de redirection>. Nous avons déjà vu cela auparavant et cela rend stdout point à déposer:
Bash suivant voit la deuxième redirection 2> & 1. Nous n'avons jamais vu cette redirection auparavant. Celui-ci duplique le descripteur de fichier 2 pour être une copie du descripteur de fichier 1 et nous obtenons:
Les deux flux ont été redirigés vers un fichier.
Attention cependant ici! L'écriture
n'est pas la même chose que d'écrire:
L'ordre des redirections est important dans Bash! Cette commande redirige uniquement la sortie standard vers le fichier. Le stderr continuera d'imprimer sur le terminal. Pour comprendre pourquoi cela se produit, reprenons les étapes. Donc, avant d'exécuter la commande, la table des descripteurs de fichiers ressemble à ceci:
Maintenant, Bash traite les redirections de gauche à droite. Il voit d'abord 2> & 1 donc il duplique stderr en stdout. Le tableau des descripteurs de fichiers devient:
Bash voit maintenant la deuxième redirection
>file
, et il redirige stdout vers le fichier:Voyez-vous ce qui se passe ici? Stdout pointe maintenant vers le fichier, mais le stderr pointe toujours vers le terminal! Tout ce qui est écrit sur stderr est toujours imprimé à l'écran! Soyez donc très, très prudent avec l'ordre des redirections!
Notez également que dans Bash, l'écriture
est exactement le même que:
la source
>&
/dev/tty0
?Les nombres se réfèrent aux descripteurs de fichiers (fd).
stdin
stdout
stderr
2>&1
redirige fd 2 vers 1.Cela fonctionne pour n'importe quel nombre de descripteurs de fichiers si le programme les utilise.
Vous pouvez regarder
/usr/include/unistd.h
si vous les oubliez:Cela dit, j'ai écrit des outils C qui utilisent des descripteurs de fichiers non standard pour la journalisation personnalisée afin que vous ne le voyiez pas sauf si vous le redirigez vers un fichier ou quelque chose.
la source
Cette construction envoie le flux d'erreur standard (
stderr
) à l' emplacement actuel de la sortie standard (stdout
) - ce problème de devise semble avoir été négligé par les autres réponses.Vous pouvez rediriger n'importe quel descripteur de sortie vers un autre en utilisant cette méthode, mais elle est le plus souvent utilisée pour canaliser
stdout
etstderr
diffuser en un seul flux pour le traitement.Quelques exemples sont:
Notez que ce dernier ne dirigera pas
stderr
versoutfile2
- il le redirige vers ce quistdout
était lorsque l'argument a été rencontré (outfile1
), puis redirigestdout
versoutfile2
.Cela permet une supercherie assez sophistiquée.
la source
some_program 2>&1 > /dev/null
ne fonctionne pas comme ça:some_program > /dev/null 2>&1
.2>&1
est une construction shell POSIX. Voici une ventilation, jeton par jeton:2
: Descripteur de fichier de sortie " Erreur standard ".>&
: Dupliquez un opérateur de descripteur de fichier de sortie (une variante de l' opérateur de redirection de sortie>
). Étant donné[x]>&[y]
, le descripteur de fichier indiqué parx
est fait pour être une copie du descripteur de fichier de sortiey
.1
« Sortie standard descripteur de fichier de sortie ».L'expression
2>&1
copie le descripteur de fichier1
à l'emplacement2
, de sorte que toute sortie écrite dans2
("erreur standard") dans l'environnement d'exécution va dans le même fichier décrit à l'origine par1
("sortie standard").Plus d'explications:
Descripteur de fichier : "Un entier unique, non négatif par processus, utilisé pour identifier un fichier ouvert à des fins d'accès au fichier."
Sortie / erreur standard : reportez-vous à la remarque suivante dans la section Redirection de la documentation du shell:
la source
2 est l'erreur standard de la console.
1 est la sortie standard de la console.
Il s'agit de l'Unix standard et Windows suit également le POSIX.
Par exemple, lorsque vous courez
l'erreur standard est redirigée vers la sortie standard, vous pouvez donc voir les deux sorties ensemble:
Après l'exécution, vous pouvez voir toutes les sorties, y compris les erreurs, dans le debug.log.
Ensuite, la sortie standard passe à out.log et l'erreur standard à err.log.
Je vous suggère d'essayer de les comprendre.
la source
perl test.pl > debug.log 2>&1
Pour répondre à votre question: il prend n'importe quelle sortie d'erreur (normalement envoyée à stderr) et l'écrit sur la sortie standard (stdout).
Ceci est utile avec, par exemple, «plus» lorsque vous avez besoin de paginer pour toutes les sorties. Certains programmes comme l'impression des informations d'utilisation dans stderr.
Pour vous aider à vous souvenir
"2> & 1" pointe simplement tout ce qui est envoyé vers stderr, vers stdout à la place.
Je recommande également de lire cet article sur la redirection d'erreur lorsque ce sujet est couvert en détail.
la source
Du point de vue d'un programmeur, cela signifie précisément ceci:
Voir la page de manuel .
Comprendre qu'il
2>&1
s'agit d'une copie explique également pourquoi ...... n'est pas la même chose que ...
Le premier enverra les deux flux vers
file
, tandis que le second enverra les erreursstdout
et la sortie ordinaire versfile
.la source
J'ai trouvé cela très utile si vous êtes un débutant, lisez ceci
Mise à jour:
sous Linux ou Unix, les programmes envoient deux sorties: sortie standard (stdout) et erreur standard (stderr). Vous pouvez rediriger ces sorties vers n'importe quel fichier.
Comme si vous faites ceci
ls -a > output.txt
Rien ne sera imprimé dans la console, toutes les sorties (stdout) sont redirigées vers le fichier de sortie.
Et si vous essayez d'imprimer le contenu d'un fichier qui ne se ferme pas, la sortie sera une erreur comme si vous imprimez test.txt qui n'est pas présent dans le répertoire courant La
cat test.txt > error.txt
sortie sera
Mais le fichier error.txt sera vide car nous redirigeons la sortie standard vers un fichier non stderr.
nous avons donc besoin d'un descripteur de fichier (un descripteur de fichier n'est rien de plus qu'un entier positif qui représente un fichier ouvert. Vous pouvez dire que le descripteur est l'identifiant unique du fichier) pour indiquer au shell quel type de sortie nous envoyons au fichier .Dans le système Unix / Linux 1 est pour stdout et 2 pour stderr .
maintenant, si vous faites cela
ls -a 1> output.txt
, cela signifie que vous envoyez une sortie standard (stdout) à output.txt.et si vous le faites, cela
cat test.txt 2> error.txt
signifie que vous envoyez l'erreur standard (stderr) à error.txt.&1
est utilisé pour référencer la valeur du descripteur de fichier 1 (stdout).Maintenant, au point
2>&1
signifie "Rediriger le stderr au même endroit que nous redirigeons le stdout"Vous pouvez maintenant le faire
cat maybefile.txt > output.txt 2>&1
la sortie standard (stdout) et l'erreur standard (stderr) seront redirigées vers output.txt.
Merci à Ondrej K. pour avoir souligné
la source
Les gens, rappelez - vous toujours paxdiablo indice de sur le courant emplacement de la cible de redirection ... Il est important de .
Ma mnémonique personnelle pour l'
2>&1
opérateur est la suivante:&
comme signifiant'and'
ou'add'
(le personnage est un esperluette - et , n'est-ce pas?)2
(stderr) vers1
(stdout) déjà / actuellement et ajouter les deux flux" .Le même mnémonique fonctionne également pour les autres redirection fréquemment utilisées
1>&2
:&
sensand
ouadd
... (vous avez l'idée de l'esperluette, oui?)1
(stdout) vers où2
(stderr) déjà / actuellement et ajouter les deux flux» .Et rappelez-vous toujours: vous devez lire les chaînes de redirections «de la fin», de droite à gauche ( pas de gauche à droite).
la source
Réf:
Tapez
/^REDIRECT
pour accéder à laredirection
section et en savoir plus ...Une version en ligne est ici: 3.6 Redirection
PS:
Beaucoup de temps,
man
était l'outil puissant pour apprendre Linux.la source
Pourvu que cela
/foo
n'existe pas sur votre système et/tmp
que ...imprimera le contenu de
/tmp
et imprimera un message d'erreur pour/foo
enverra le contenu de
/tmp
à/dev/null
et imprimera un message d'erreur pour/foo
fera exactement la même chose (notez le 1 )
imprimera le contenu de
/tmp
et enverra le message d'erreur à/dev/null
enverra la liste ainsi que le message d'erreur à
/dev/null
est un raccourci
la source
Cela revient à transmettre l'erreur à la sortie standard ou au terminal.
Autrement dit,
cmd
n'est pas une commande:L'erreur est envoyée au fichier comme ceci:
L'erreur standard est envoyée au terminal.
la source
0 pour entrée, 1 pour stdout et 2 pour stderr.
Un conseil :
somecmd >1.txt 2>&1
est correct, toutsomecmd 2>&1 >1.txt
est totalement faux sans aucun effet!la source
unix_commands 2>&1
Ceci est utilisé pour imprimer des erreurs sur le terminal.
Ce qui suit illustre le processus
&2
"tampon" d' adresse de mémoire d'erreur standard , à partir duquel le flux d'erreurs standard fait2
référence.&1
"buffer", à partir de laquelle le flux de sortie standard fait1
référence.Prenez donc le
unix_commands
flux d'erreurs standard2
et redirigez>
le flux (d'erreurs) vers l'adresse de mémoire de sortie standard&1
, afin qu'ils soient diffusés sur le terminal et imprimés.la source