Como alguns programas de terminal podem ignorar redirecionamentos e pipes?

0

Eu estive mexendo na minha placa de rede hoje à noite, quando notei algo quando corro ip link help . Aqui estão dois casos quando notei algo diferente:

ip link help | grep set

e

ip link help > ip_link_help.txt

O primeiro comando não tem efeito, ou seja, em vez de redirecionar a saída de ip link help do stdout para grep , o pipe é simplesmente ignorado e a saída de ip link help é enviada para o stdout .

O segundo caso é um pouco diferente. Embora ip link help ignore o símbolo de redirecionamento > e apenas imprima no stdout , o arquivo file.txt é criado de qualquer maneira (mas está vazio).

    
por Hanlon 03.10.2018 / 20:58

1 resposta

3

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.

    
por 03.10.2018 / 21:02