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
?
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
.
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.
I numeri si riferiscono ai descrittori di file (fd).
stdin
.stdout
.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.