Nel guscio, cosa significa " 2>&1 "?

In una shell Unix, se voglio combinare stderr e stdout nel flusso stdout per ulteriori manipolazioni, posso aggiungere quanto segue alla fine del mio comando:

2>&1

Quindi, se voglio usare head sull'output di g++, posso fare qualcosa del genere:

g++ lots_of_errors 2>&1 | head

così posso vedere solo i primi errori.

Ho sempre problemi a ricordare questo, e devo costantemente andare a cercarlo, ed è principalmente perché non capisco completamente la sintassi di questo particolare trucco.

Qualcuno può rompere questo e spiegare carattere per carattere cosa significa 2>&1?

Soluzione

Il descrittore di file 1 è l'uscita standard (stdout); Il descrittore di file 2 è l'errore standard (stderr).

Ecco un modo per ricordare questo costrutto (sebbene non sia del tutto accurato): all'inizio, 2>1 può sembrare un buon modo per reindirizzare stderr a stdout. Tuttavia, sarà effettivamente interpretato come "reindirizzare stderr a un file chiamato 1". & indica che ciò che segue è un descrittore di file e non un nome di file. Quindi il costrutto diventa: 2>&1.

Commentari (18)
echo test > afile.txt

reindirizza lo stdout a afile.txt. Questo è lo stesso che fare

echo test 1> afile.txt

Per reindirizzare stderr, si fa:

echo test 2> afile.txt

>& è la sintassi per reindirizzare un flusso ad un altro descrittore di file - 0 è stdin, 1 è stdout, e 2 è stderr.

Potete reindirizzare stdout a stderr facendo:

echo test 1>&2 # or echo test >&2

O viceversa:

echo test 2>&1

Quindi, in breve... 2> reindirizza stderr ad un file (non specificato), aggiungendo &1 reindirizza stderr a stdout.

Commentari (5)

I numeri si riferiscono ai descrittori di file (fd).

  • Zero è stdin.
  • Uno è stdout.
  • Due è stderr.

2>&1 reindirizza fd 2 a 1.

Questo funziona per qualsiasi numero di descrittori di file, se il programma li usa.

Puoi guardare in /usr/include/unistd.h se li dimentichi:

/* Standard file descriptors.  */
#define STDIN_FILENO    0   /* Standard input.  */
#define STDOUT_FILENO   1   /* Standard output.  */
#define STDERR_FILENO   2   /* Standard error output.  */

Detto questo, ho scritto strumenti C che usano descrittori di file non standard per il logging personalizzato in modo da non vederlo a meno che non lo si reindirizzi a un file o qualcosa del genere.

Commentari (0)