bash - vers - linux>& 1




Dans le shell, que signifie "2> & 1"? (10)

Redirection d'entrée

La redirection d'entrée entraîne l'ouverture du fichier dont le nom résulte de l'extension de mot à lire dans le descripteur de fichier n, ou l'entrée standard (descripteur de fichier 0) si n n'est pas spécifié.

Le format général de redirection des entrées est:

      [n]<word

Redirection de sortie

La redirection de sortie provoque l'ouverture du fichier dont le nom résulte de l'expansion du mot pour l'écriture sur le 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 existe, il est tronqué à zéro.

Le format général de redirection de sortie est:

      [n]>word

Déplacer des descripteurs de fichiers

Déplacement de descripteurs de fichiers L'opérateur de redirection

      [n]<&digit-

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

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

      [n]>&digit-

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

ref:

man bash
tapez /^REDIRECT pour accéder à la section de redirection , en savoir plus ..

une version en ligne ici:
http://www.gnu.org/software/bash/manual/bashref.html#Redirections

ps:

beaucoup de temps, l' man était l'outil puissant pour apprendre linux

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 peux voir que les premières erreurs.

J'ai toujours du mal à me souvenir de cela, et je dois constamment aller voir, et c'est principalement parce que je ne comprends pas complètement la syntaxe de cette astuce particulière. Est-ce que quelqu'un peut casser cela et expliquer par caractère ce que "2> & 1" veut dire?


Quelques astuces sur la redirection

Certaines particularités de syntaxe à ce sujet peuvent avoir des comportements importants. Il y a quelques petits exemples sur les redirections, STDERR , STDOUT et l' ordre des arguments.

1 - Écrasement ou ajout?

Symbole > redirection moyenne.

  • > mean envoie à l'ensemble du fichier complété , en écrasant la cible si elle existe (voir la fonction de noclobber bash à # 3 plus tard).
  • >> signifie envoyer en plus à ajouter à la cible si elle 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 :

$ 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

(Je m'attends à ce 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 dump STDERR vers la console, il ne semble pas être le comportement attendu ... Mais ...

Si vous voulez faire un post-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 précédent paragraphe, 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 petites astuces sur les redirections, pour faire différentes opérations 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

Nota: &9 descripteur se produirait spontanément à cause de ) 9>&2 .

Addendum: nota! Avec la nouvelle version de bash ( >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 un tel formatage de sortie en cascade:

$ ((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 traversent un troisième filtre de commande.

3 - Un mot sur l'option noclobber et >| syntaxe

C'est à propos de l' écrasement :

Alors que set -o noclobber indique à bash de ne pas écraser un fichier existant, le fichier >| la syntaxe vous laisse passer 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 à travers avec >| :

$ 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ésactivation de cette option et / ou demande si elle est déjà définie.

$ 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 - Dernier tour et plus ...

Pour rediriger les deux sorties d'une commande donnée, nous voyons qu'une syntaxe correcte pourrait être:

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

pour ce cas particulier , il existe 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 aussi une syntaxe correcte:

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

4b- Maintenant, je vais vous laisser penser à:

$ 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 d' informations

vous pourriez lire le manuel en frappant:

man -Len -Pless\ +/^REDIRECTION bash

dans une console bash ;-)


2 est l'erreur standard de la console.

1 est la sortie standard de la console.

C'est le standard Unix, Windows suit également le POSIX. Par exemple, quand vous courez

perl test.pl 2>&1

L'erreur standard est redirigée vers la sortie standard afin que vous puissiez 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 fichier debug.log.

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

La sortie standard est ensuite envoyée à out.log et l'erreur standard à err.log.

Je vous suggère d'essayer de comprendre cela.


C'est juste comme paasing l'erreur à la stdout ou au terminal. c'est à dire . cmd n'est pas une commande $ cmd 2> nom du fichier cat nom de la commande introuvable

L'erreur envoyée au fichier comme cette erreur 2> & 1 envoyée au terminal


Du point de vue du programmeur, cela signifie précisément ceci:

dup2(1, 2);

Voir la page de manuel .

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

command >file 2>&1

... n'est pas la même chose que ...

command 2>&1 >file

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


J'ai trouvé ce brillant post sur la redirection: Tout sur les redirections

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

$ commande &> fichier

Ce one-liner utilise l'opérateur &> pour rediriger les deux flux de sortie - stdout et stderr - de la commande au fichier. C'est le 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 ait redirigé les deux flux:

Comme vous pouvez le voir, stdout et stderr pointent maintenant vers un fichier. Tout ce qui est écrit dans stdout et stderr est écrit dans un fichier.

Il existe plusieurs façons de rediriger les deux flux vers la même destination. Vous pouvez rediriger chaque flux les uns après les autres:

$ command> fichier 2> & 1

C'est un moyen beaucoup plus commun de rediriger les deux flux vers un fichier. La première sortie stdout est redirigée vers un fichier, puis stderr est dupliqué pour être identique à stdout. Donc les deux flux finissent par pointer vers le fichier.

Lorsque bash voit plusieurs redirections, il les traite de gauche à droite. Passons en revue les étapes et voyons comment cela se passe. 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 l'avons vu auparavant et cela fait stdout pointer vers le fichier:

Le prochain bash voit la deuxième redirection 2> & 1. Nous n'avons pas vu cette redirection auparavant. Celui-ci duplique le descripteur de fichier 2 pour qu'il soit une copie du descripteur de fichier 1 et nous obtenons:

Les deux flux ont été redirigés vers le fichier.

Cependant faites attention ici! L'écriture:

commande> fichier 2> & 1

N'est-ce pas la même chose que d'écrire:

$ command 2> & 1> fichier

L'ordre des redirections est important dans bash! Cette commande redirige uniquement la sortie standard vers le fichier. Le stderr sera toujours imprimer sur le terminal. Pour comprendre pourquoi cela se produit, répétons 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 à stdout. La table des descripteurs de fichiers devient:

Maintenant, bash voit le deuxième fichier de redirection> et 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 imprimé à l'écran! Soyez donc très, très prudent avec l'ordre des redirections!

Notez également que dans bash, écrire ceci:

$ commande &> fichier

Est-ce exactement la même chose que:

Commande $> & fichier


Les chiffres se réfèrent aux descripteurs de fichier (fd).

  • Zéro est stdin
  • L'un est stdout
  • Deux est stderr

2>&1 redirige fd 2 à 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:

/* 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 C qui utilisent des descripteurs de fichiers non standard pour la journalisation personnalisée, donc vous ne le voyez pas à moins de le rediriger vers un fichier ou quelque chose comme ça.


Les gens, souvenez-vous toujours de l' indice de paxdiablo sur l'emplacement actuel de la cible de redirection ... C'est important.

Ma mnémonique personnelle pour l'opérateur 2>&1 est la suivante:

  • Pensez à & comme signifiant 'and' ou 'add' (le caractère est un ampers - et n'est-ce pas?)
  • Donc, il devient: 'rediriger 2 (stderr) vers où 1 (stdout) est déjà / est actuellement et ajouter les deux flux' .

La même méthode mnémonique fonctionne pour l'autre redirection fréquemment utilisée, 1>&2 :

  • Penser & signifier and ou add ... (vous avez l'idée de l'esperluette, oui?)
  • Donc, il devient: 'rediriger 1 (stdout) vers où 2 (stderr) est déjà / est actuellement et ajouter les deux flux' .

Et rappelez-vous toujours: vous devez lire des chaînes de redirections 'de la fin', de droite à gauche ( pas de gauche à droite).


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

$ 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 affichera un message d'erreur pour /foo

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

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

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

affichera le contenu de /tmp et enverra le message d'erreur à /dev/null

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

enverra la liste ainsi que le message d'erreur à /dev/null

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

est une abréviation


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

2 : Descripteur de fichier de sortie " Erreur standard ".

>& : Dupliquer 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 désigné par x est fait pour être une copie du descripteur de fichier de sortie y .

1 Descripteur de fichier de sortie "Sortie standard ".

L'expression 2>&1 copie le descripteur de fichier 1 à l'emplacement 2 , donc 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").

Plus d'explications:

Descripteur de fichier : "Un entier unique non négatif par processus utilisé pour identifier un fichier ouvert dans le but d'accéder au fichier."

Sortie / erreur standard : Reportez-vous à la remarque suivante dans la section Redirection de la documentation du shell:

Les fichiers ouverts sont représentés par des nombres décimaux commençant par zéro. La plus grande valeur possible est définie par l'implémentation; Cependant, toutes les mises en œuvre doivent prendre en charge au moins 0 à 9, inclusivement, pour une utilisation par l'application. Ces numéros sont appelés "descripteurs de fichiers". Les valeurs 0, 1 et 2 ont une signification spéciale et des utilisations conventionnelles et sont impliquées par certaines opérations de réacheminement; ils sont appelés entrée standard, sortie standard et erreur standard, respectivement. Les programmes prennent généralement leur entrée à partir de l'entrée standard et écrivent la sortie sur la sortie standard. Les messages d'erreur sont généralement écrits sur l'erreur standard. Les opérateurs de réacheminement peuvent être précédés d'un ou plusieurs chiffres (sans caractères d'intervention autorisés) pour désigner le numéro de descripteur de fichier.





redirect