Em uma shell Unix, se eu quiser combinar stderr
e stdout
no fluxo stdout
para manipulação posterior, eu posso anexar o seguinte no final do meu comando:
2>&1
Então, se eu quiser usar head
na saída de g++
, eu posso fazer algo como isto:
g++ lots_of_errors 2>&1 | head
para que eu possa ver apenas os primeiros erros.
Tenho sempre dificuldade em lembrar-me disto, e tenho constantemente de ir ver, e é principalmente porque não compreendo bem a sintaxe deste truque em particular.
Alguém pode dividir isto e explicar personagem por personagem o que significa 2>&1
?
O descritor de arquivo 1 é a saída padrão (stdout
).
O descritor de arquivo 2 é o erro padrão (stderr
).
Aqui está uma maneira de lembrar esta construção (embora não seja totalmente precisa): no início, 2>1
pode parecer uma boa maneira de redirecionar stderr
para stdout
. No entanto, ele será realmente interpretado como "redirecionar stderr
para um arquivo chamado 1
". &
indica que o que se segue é um descritor de arquivo e não um nome de arquivo. Assim, a construção se torna: 2>&1
.
echo test > afile.txt
redireciona o stdout para afile.txt
. Isto é o mesmo que fazer
echo test 1> afile.txt
Para redireccionar a stderr, você faz:
echo test 2> afile.txt
A sintaxe para redirecionar um fluxo para outro descritor de arquivo - 0 é stdin, 1 é stdout, e 2 é stderr.
Você pode redirecionar a stdout para stderr fazendo:
echo test 1>&2 # or echo test >&2
Ou vice versa:
echo test 2>&1
Então, em resumo... 2>
redireciona stderr para um arquivo (não especificado), anexando &1
redireciona stderr para stdout.
Os números referem-se aos descritores de arquivo (fd).
stdin
.2>&1
redireciona o fd 2 para 1.
Isto funciona para qualquer número de descritores de ficheiros se o programa os utilizar.
Você pode olhar para /usr/include/unistd.h
se você esquecê-los:
/* Standard file descriptors. */
#define STDIN_FILENO 0 /* Standard input. */
#define STDOUT_FILENO 1 /* Standard output. */
#define STDERR_FILENO 2 /* Standard error output. */
Dito isto, escrevi ferramentas em C que utilizam descritores de arquivo não-padronizados para o registro personalizado, para que você não o veja a menos que você o redirecione para um arquivo ou algo assim.