ip link help
é impresso no erro padrão (stderr, descritor de arquivo 2
); sua saída padrão (stdout, descritor de arquivo 1
) não recebe dados. Normalmente, os dois fluxos vão para o terminal, então você não pode diferenciá-los à primeira vista. |
ou >
afeta a saída padrão. Depois de usá-lo, você sabe que todos os dados que forem redirecionados devem ter sido destinados ao stdout; todo o resto - para outro lugar: geralmente para stderr, embora alguns programas imprimam alguns dados diretamente para o terminal ( ip
não é um deles).
No seu primeiro caso, você pode redirecionar o stderr para o descritor de arquivo do stdout e, em seguida, criar um canal:
ip link help 2>&1 | grep set
onde 2>&1
diz ao shell para redirecionar o descritor de arquivo 2
para qualquer que seja o descritor de arquivo 1
. Com esta sintaxe, se o comando imprimisse algo para stdout e stderr, tudo chegaria em grep
.
No segundo caso, o shell cria (se necessário) e trunca o arquivo antes que ip
seja executado. Você pode ver isso invocando
a_command_that_doesnt_even_exist > foo.txt
foo.txt
será criado apesar do erro óbvio. Isso é porque ele é criado primeiro, antes mesmo que o shell tente executar o comando.
Para capturar stderr para o arquivo, use 2>
, que redireciona apenas o stderr:
ip link help 2> ip_link_help.txt
Similarmente, 1>
redireciona somente o stdout. Curto >
que você usou é estritamente equivalente a 1>
.
Um exemplo artificial de um comando que imprime no terminal de três maneiras diferentes é
echo "standard output"; echo "standard error" >&2; echo "terminal" >/dev/tty
A saída é:
standard output
standard error
terminal
Você pode redirecionar facilmente as duas primeiras linhas. Tente isto:
(echo "standard output"; echo "standard error" >&2; echo "terminal" >/dev/tty) >stdout.txt 2>stderr.txt
Isso ainda imprimirá a última linha.