Dans la coquille, que signifie "2>&1"?

dans un shell Unix, si je veux combiner stderr et stdout dans le flux stdout pour d'autres manipulations, 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 vois que les premières erreurs.

j'ai toujours du mal à m'en souvenir, et je constamment avoir à aller le chercher, et c'est principalement parce que je ne comprends pas tout la syntaxe de cette astuce particulière.

Quelqu'un peut-il briser ceci et expliquer le caractère par caractère ce que 2>&1 signifie?

1793
demandé sur Ricardo 2009-05-04 02:57:00

15 réponses

le descripteur de fichier 1 est la sortie standard ( stdout ).

Le descripteur de fichier 2 est l'erreur type ( stderr ).

Voici une façon de se souvenir de cette construction (bien qu'elle ne soit pas entièrement exacte): au début, 2>1 peut sembler un bon moyen de rediriger stderr à 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 pas un nom de fichier. Ainsi la construction devient: 2>&1 .

2000
répondu Ayman Hourieh 2018-05-09 20:18:47
echo test > afile.txt

redirige stdout vers afile.txt . C'est la même chose que 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é), en ajoutant &1 redirige stderr vers stdout.

495
répondu dbr 2018-07-04 20:36:11

Quelques trucs à propos de la redirection

certaines particularités syntaxiques à ce sujet peuvent avoir des comportements importants. Il y a quelques petits exemples de redirections, STDERR , STDOUT , et des arguments ordonnant .

1 - l'Écrasement ou l'ajout d'?

symbole > signifie redirection .

  • > moyenne Envoyer à l'ensemble du fichier complété , remplacer cible s'il existe (voir noclobber Bash caractéristique à #3 plus tard).
  • >> signifie envoyer serait ajouter à la cible, si elle existe.

Dans tous les cas, le fichier est créé s'ils n'existent pas.

2 - La ligne de commande shell est l'ordre dépendant de la!!

pour tester ceci, nous avons besoin de une commande simple qui enverra quelque chose sur les deux sorties :

$ ls -ld /tmp /tnt
ls: cannot access /tnt: No such file or directory
drwxrwxrwt 118 root root 196608 Jan  7 11:49 /tmp

$ ls -ld /tmp /tnt >/dev/null
ls: cannot access /tnt: No such file or directory

$ ls -ld /tmp /tnt 2>/dev/null
drwxrwxrwt 118 root root 196608 Jan  7 11:49 /tmp

(en espérant que vous n'ayez pas de répertoire nommé /tnt , bien sûr ;). Eh bien, nous l'avons!!

alors, voyons voir:

$ ls -ld /tmp /tnt >/dev/null
ls: cannot access /tnt: No such file or directory

$ ls -ld /tmp /tnt >/dev/null 2>&1

$ ls -ld /tmp /tnt 2>&1 >/dev/null
ls: cannot access /tnt: No such file or directory

la dernière ligne de commande renvoie STDERR à la console, et cela ne semble pas être le comportement attendu... Mais...

Si vous voulez faire quelques filtrage sur une sortie, l'autre ou les deux:

$ ls -ld /tmp /tnt | sed 's/^.*$/<-- & --->/'
ls: cannot access /tnt: No such file or directory
<-- drwxrwxrwt 118 root root 196608 Jan  7 12:02 /tmp --->

$ ls -ld /tmp /tnt 2>&1 | sed 's/^.*$/<-- & --->/'
<-- ls: cannot access /tnt: No such file or directory --->
<-- drwxrwxrwt 118 root root 196608 Jan  7 12:02 /tmp --->

$ ls -ld /tmp /tnt >/dev/null | sed 's/^.*$/<-- & --->/'
ls: cannot access /tnt: No such file or directory

$ ls -ld /tmp /tnt >/dev/null 2>&1 | sed 's/^.*$/<-- & --->/'

$ ls -ld /tmp /tnt 2>&1 >/dev/null | sed 's/^.*$/<-- & --->/'
<-- ls: cannot access /tnt: No such file or directory --->

notez que la dernière ligne de commande dans ce paragraphe est exactement la même que dans le paragraphe précédent, où j'ai écrit ne semblent pas être le comportement attendu (donc, cela pourrait même être un comportement attendu).

Eh bien, il y a quelques trucs sur les redirections, pour faire une opération différente sur les deux sorties :

$ ( ls -ld /tmp /tnt | sed 's/^/O: /' >&9 ) 9>&2  2>&1  | sed 's/^/E: /'
O: drwxrwxrwt 118 root root 196608 Jan  7 12:13 /tmp
E: ls: cannot access /tnt: No such file or directory

Note: &9 descripteur se produirait spontanément en raison de ) 9>&2 .

Addendum: nota! avec la nouvelle version de ( >4.0 ) il y a une nouvelle fonctionnalité et une syntaxe plus sexy pour faire ce genre de choses:

$ ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /')
O: drwxrwxrwt 17 root root 28672 Nov  5 23:00 /tmp
E: ls: cannot access /tnt: No such file or directory

et enfin pour une telle production en cascade mise en forme:

$ ((ls -ld /tmp /tnt |sed 's/^/O: /' >&9 ) 2>&1 |sed 's/^/E: /') 9>&1| cat -n
     1  O: drwxrwxrwt 118 root root 196608 Jan  7 12:29 /tmp
     2  E: ls: cannot access /tnt: No such file or directory

Addendum: nota! même nouvelle syntaxe, dans les deux sens:

$ cat -n <(ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /'))
     1  O: drwxrwxrwt 17 root root 28672 Nov  5 23:00 /tmp
     2  E: ls: cannot access /tnt: No such file or directory

STDOUT passe par un filtre spécifique, STDERR à un autre et finalement les deux sorties fusionnées passent par un troisième filtre de commande.

3 - un mot au sujet de noclobber option et >| syntaxe

c'est à propos de overwriting :

alors que set -o noclobber instruit bash à pas écraser tout fichier existant, la syntaxe >| vous laisser passer par cette limitation:

$ testfile=$(mktemp /tmp/testNoClobberDate-XXXXXX)

$ date > $testfile ; cat $testfile
Mon Jan  7 13:18:15 CET 2013

$ date > $testfile ; cat $testfile
Mon Jan  7 13:18:19 CET 2013

$ date > $testfile ; cat $testfile
Mon Jan  7 13:18:21 CET 2013

le fichier est écrasé à chaque fois, bien maintenant:

$ set -o noclobber

$ date > $testfile ; cat $testfile
bash: /tmp/testNoClobberDate-WW1xi9: cannot overwrite existing file
Mon Jan  7 13:18:21 CET 2013

$ date > $testfile ; cat $testfile
bash: /tmp/testNoClobberDate-WW1xi9: cannot overwrite existing file
Mon Jan  7 13:18:21 CET 2013

Passer par >| :

$ date >| $testfile ; cat $testfile
Mon Jan  7 13:18:58 CET 2013

$ date >| $testfile ; cat $testfile
Mon Jan  7 13:19:01 CET 2013

désactivant cette option et/ou demandant si elle est déjà activée.

$ set -o | grep noclobber
noclobber           on

$ set +o noclobber

$ set -o | grep noclobber
noclobber           off

$ date > $testfile ; cat $testfile
Mon Jan  7 13:24:27 CET 2013

$ rm $testfile

4 - le Dernier pli et plus...

Pour rediriger les deux sortie à partir d'une commande donnée, nous voyons qu'un droit de la syntaxe pourrait être:

$ ls -ld /tmp /tnt >/dev/null 2>&1

pour ce cas spécial , il y a une syntaxe de raccourci: &> ... ou >&

$ ls -ld /tmp /tnt &>/dev/null

$ ls -ld /tmp /tnt >&/dev/null

Nota: Si 2>&1 existent, 1>&2 est un bonne syntaxe aussi:

$ ls -ld /tmp /tnt 2>/dev/null 1>&2

4b-maintenant, je vous laisse réfléchir:

$ ls -ld /tmp /tnt 2>&1 1>&2  | sed -e s/^/++/
++/bin/ls: cannot access /tnt: No such file or directory
++drwxrwxrwt 193 root root 196608 Feb  9 11:08 /tmp/

$ ls -ld /tmp /tnt 1>&2 2>&1  | sed -e s/^/++/
/bin/ls: cannot access /tnt: No such file or directory
drwxrwxrwt 193 root root 196608 Feb  9 11:08 /tmp/

4C - si vous êtes intéressé par plus informations

vous pouvez lire le manuel en tapant:

man -Len -Pless\ +/^REDIRECTION bash

dans un de la console ;-)

264
répondu F. Hauri 2018-07-04 20:41:51

les numéros renvoient aux descripteurs de fichier (fd).

  • Zéro stdin
  • l'Un est stdout
  • Deux, c'est stderr

2>&1 redirige fd 2 vers 1.

Cela fonctionne pour n'importe quel nombre de descripteurs de fichier si le programme utilise.

vous pouvez regarder /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.  */

qui dit que j'ai écrit des outils C qui utilisent des descripteurs de fichiers non standard pour la journalisation personnalisée donc vous ne le voyez pas à moins que vous ne le redirigiez vers un fichier ou quelque chose.

71
répondu Colin Burnett 2012-11-06 01:25:12

j'ai trouvé ce post brillant sur la redirection: tout sur les redirections

rediriger la sortie standard et l'erreur standard vers un fichier

commande $ &>fichier

cette doublure utilise l'opérateur &> pour rediriger les flux de sortie-stdout et stderr - de la commande au fichier. C'est du Bash raccourci 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:

Enter image description here

comme vous pouvez le voir, stdout et stderr pointent maintenant vers file . Donc tout ce qui est écrit à stdout et stderr est écrit à file .

Il y a plusieurs façons de rediriger les deux flux vers la même destination. Vous pouvez rediriger chaque flux, l'un après l'autre:

$ commande >fichier 2>&1

c'est une façon beaucoup plus courante de rediriger les deux flux vers un fichier. D'abord stdout est redirigé vers file, puis stderr est dupliqué pour être le même que stdout. Donc les deux flux finissent par pointer vers file .

quand 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 une commande, la table de descripteur de fichier de Bash ressemble à ceci:

Enter image description here

traite maintenant Bash le premier fichier de redirection>. Nous avons déjà vu cela et cela fait de stdout point un fichier:

Enter image description here

prochain Bash voit le 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:

Enter image description here

les deux flux ont été redirigés vers file.

cependant faites attention ici! Ecriture

commande > Fichier 2> & 1

n'est pas la même que écriture:

$ commande 2>&1 >fichier

L'ordre des redirections questions dans le coup! Cette commande redirige uniquement la sortie standard vers le fichier. Le stderr imprimera toujours au terminal. Pour comprendre pourquoi cela se produit, revoyons les étapes. Ainsi, avant d'exécuter la commande, la table de descripteur de fichier ressemble à ceci:

Enter image description here

maintenant Bash traite des redirections de gauche à droite. Il voit d'abord 2>&1 ainsi il duplique stderr à stdout. La table des descripteurs de fichier devient:

Enter image description here

maintenant Bash voit la deuxième redirection, >file , et il redirige stdout au fichier:

Enter image description here

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 à stderr est imprimé à l'écran! Soyez donc très, très prudent avec l'ordre des redirections!

notez aussi Qu'en Bash, en écrivant

commande $ &>fichier

est exactement le même que:

$ command >&fichier

53
répondu Deen John 2018-07-05 03:43:35

cette construction envoie le flux d'erreur standard ( stderr ) au courant emplacement de la sortie standard ( stdout ) - cette question de monnaie semble avoir été négligée par les autres réponses.

vous pouvez rediriger n'importe quelle poignée de sortie à une autre en utilisant cette méthode, mais il est le plus souvent utilisé pour canaliser stdout et stderr flux dans un seul flux pour le traitement.

quelques exemples::

# Look for ERROR string in both stdout and stderr.
foo 2>&1 | grep ERROR

# Run the less pager without stderr screwing up the output.
foo 2>&1 | less

# Send stdout/err to file (with append) and terminal.
foo 2>&1 |tee /dev/tty >>outfile

# Send stderr to normal location and stdout to file.
foo >outfile1 2>&1 >outfile2

Notez que le dernier, pas direct stderr à outfile2 - il redirige vers ce stdout a été lors de l'argument a été rencontrée ( outfile1 ) et puis redirige stdout à outfile2 .

cela permet quelques ruses assez sophistiquées.

50
répondu paxdiablo 2009-06-26 08:39:06

2>&1 est un shell POSIX construire. Voici une répartition, jeton par jeton:


2 : " erreur Standard sortie " du descripteur de fichier.

>& : dupliquer un descripteur de fichier de sortie opérateur (une variante de Redirection de sortie opérateur > ). Étant donné [x]>&[y] , le descripteur de fichier indiqué par x est fait pour être une copie du descripteur de fichier de sortie y .

1 " sortie Standard " descripteur de fichier de sortie.

l'expression 2>&1 copie le descripteur de fichier 1 à l'emplacement 2 , de sorte que toute sortie écrite à 2 ("erreur standard") dans l'environnement d'exécution va au même fichier décrit à l'origine par 1 ("sortie standard").


autre explication:

descripteur de fichier : "un entier unique par processus, non négatif, utilisé pour identifier un fichier ouvert aux fins de l'accès au fichier."

sortie/erreur Standard : se référer à la note suivante dans la section Redirection de la documentation shell:

les fichiers ouverts sont représentés par des nombres décimaux commençant par zéro. La valeur la plus élevée possible est définie par la mise en œuvre; toutefois, toutes les mises en œuvre doivent supporter au moins 0 à 9, inclusivement, pour utilisation par l'application. Ces numéros sont appelés "descripteurs de fichiers". Les valeurs 0, 1 et 2 ont un sens particulier et des utilisations conventionnelles et sont impliquées par certaines opérations de redirection; elles sont appelées entrées standard, la sortie, et l'erreur standard, Respectivement. Les programmes prennent généralement leur entrée standard, et écrire la sortie sur la sortie standard. Les messages d'erreur sont généralement écrits sur l'erreur standard. Les opérateurs de redirection peuvent être précédés d'un ou plusieurs chiffres (sans caractères intermédiaires autorisés) pour désigner le numéro du descripteur de fichier.

14
répondu wjordan 2016-12-25 06:43:43

pour répondre à votre question: il prend n'importe quelle sortie d'erreur (normalement envoyé à stderr) et l'écrit à la sortie standard (stdout).

c'est utile avec, par exemple 'plus' quand vous avez besoin de pagination pour toutes les sorties. Certains programmes comme l'impression des informations d'utilisation dans stderr.

pour vous aider à vous souvenir

  • 1 = sortie standard (où les programmes impriment la sortie normale)
  • 2 = Erreur type (où programmes erreurs d'impression)

"2>&1" Il suffit de pointer tout ce qui est envoyé à stderr, à stdout à la place.

je recommande aussi la lecture ce post sur la redirection d'erreur où ce sujet est couvert en détail.

12
répondu Andrioid 2009-05-03 23:24:58

2 est l'erreur standard de la console.

1 est la sortie standard de la console.

C'est le standard Unix, et Windows suit également le POSIX.

E. G. quand vous courez

perl test.pl 2>&1

l'erreur standard est redirigée vers la sortie standard, de sorte que vous pouvez voir les deux sorties ensemble:

perl test.pl > debug.log 2>&1

Après l'exécution, vous pouvez voir toutes les sorties, y compris les erreurs, dans le débogage.journal.

perl test.pl 1>out.log 2>err.log

puis sortie standard.journal, et la marge d'erreur err.journal.

je vous suggère d'essayer de comprendre ces.

12
répondu Marcus Thornton 2018-07-05 03:14:53

du point de vue d'un programmeur, cela signifie précisément ceci:

dup2(1, 2);

Voir la l'homme page .

comprendre que 2>&1 est une copie explique aussi pourquoi ...

command >file 2>&1

... n'est pas le même que ...

command 2>&1 >file

le premier enverra les deux flux à file , tandis que le second enverra des erreurs à stdout , et Sortie ordinaire dans file .

10
répondu ams 2015-12-03 10:20:34

les Gens, rappelez-vous toujours paxdiablo , allusion à propos de la actuel emplacement de la cible de redirection... est important.

mon mnémonique personnel pour l'opérateur 2>&1 est ceci:

  • pensez à & comme signifiant 'and' ou 'add' (le caractère est un ampères - et , n'est-ce pas?)
  • ainsi il devient: 'redirect 2 (stderr) à l'endroit où 1 (stdout) est déjà/actuellement et ajouter les deux flux" .

les mêmes œuvres mnémoniques pour l'autre redirection fréquemment utilisé aussi, 1>&2 :

  • pensez à & qui signifie and ou add ... (vous avez l' idée à propos de l'esperluette, oui?)
  • ainsi il devient: 'redirect 1 (stdout) à l'endroit où 2 (stderr) est déjà/actuellement et ajouter les deux flux" .

et rappelez-vous toujours: vous devez lire les chaînes de redirections 'du bout', de droite à gauche ( pas de gauche à droite).

4
répondu Kurt Pfeifle 2012-07-01 10:47:27

pourvu que /foo n'existe pas sur votre système et /tmp n'existe pas ...

$ ls -l /tmp /foo

affichera le contenu de /tmp et affichera un message d'erreur pour /foo

$ ls -l /tmp /foo > /dev/null

enverra le contenu de /tmp à /dev/null et imprimera un message d'erreur pour /foo

$ ls -l /tmp /foo 1> /dev/null

fera exactement la même chose (notez la 1 )

$ ls -l /tmp /foo 2> /dev/null

imprime le contenu de /tmp et envoie le message d'erreur /dev/null

$ ls -l /tmp /foo 1> /dev/null 2> /dev/null

enverra à la fois l'inscription ainsi que le message d'erreur /dev/null

$ ls -l /tmp /foo > /dev/null 2> &1

est une abréviation de

4
répondu Matijs 2016-09-01 20:58:04

c'est comme passer l'erreur au stdout ou au terminal.

C'est-à-dire, cmd n'est pas une commande:

$cmd 2>filename
cat filename

command not found

l'erreur est envoyée au fichier comme ceci:

2>&1
L'erreur Type

est envoyée au terminal.

4
répondu Kalanidhi 2018-07-05 03:17:17

Redirection D'Entrée

Redirection de l'entrée provoque le fichier dont le nom résultats de l'extension de word à ouvrir pour la lecture sur Fichier descripteur n, ou l'entrée standard (descripteur de fichier 0) si n est n'est pas spécifié.

le format général pour rediriger l'entrée est:

[n]<word

Redirection De La Sortie

Redirection de la sortie provoque le fichier dont nom résulte de l'expansion de word à ouvrir pour l'écriture sur descripteur de fichier n, ou la sortie standard (descripteur de fichier 1) si n n'est pas spécifié. Si le fichier n'existe pas il est créé; s'il n'existe pas, il est tronqué à la taille zéro.

le format général pour rediriger la sortie est:

[n]>word

Déplacement Des Descripteurs De Fichier

l'opérateur de redirection,

[n]<&digit-

déplace le chiffre du descripteur de fichier vers le descripteur de fichier n, ou le l'entrée standard (descripteur de fichier 0) si n n'est pas spécifié. le chiffre est fermé après avoir été dupliqué à N.

de même, l'opérateur de redirection

[n]>&digit-

déplace le chiffre du descripteur de fichier vers le descripteur de fichier n, ou le la sortie standard (descripteur de fichier 1) si n n'est pas spécifié.

Ref:

man bash

Tapez /^REDIRECT pour localiser la section redirection , et en savoir plus...

une version en ligne est ici: 3.6 Redirections

PS:

beaucoup de fois, man était l'outil puissant pour apprendre Linux.

2
répondu yurenchen 2018-07-05 03:25:15

0 pour input, 1 pour stdout et 2 pour stderr.

Une Astuce : somecmd >1.txt 2>&1 est correct, tandis que somecmd 2>&1 >1.txt est totalement faux sans effet!

0
répondu fzyzcjy 2016-07-25 09:46:19