Quando usar o redirecionamento para stderr em scripts de shell

15

Eu sei que utilitários bem comportados, como grep , saem mensagens "normais" para stdout e mensagens de erro para stderr.

$ grep '^foo' file1 file2
file1:foo
grep: file2: No such file or directory

Quando estou escrevendo scripts de shell, geralmente acho difícil decidir qual saída e quais mensagens devo apresentar no stderr ou se devo me preocupar.

Gostaria de saber sobre as boas práticas: quando o redirecionamento de alguma mensagem para o stderr é necessário e razoável e quando não?

"Depende", claro, mas você tem algumas idéias que me ajudariam a tomar essas decisões?

Para que essa pergunta subjetiva se encaixe no formato, gostaria de incentivar respostas que abordem o "porquê" e sejam informadas pela experiência e, se possível, apoiadas por fatos.

glts
fonte
@rush explica perfeitamente. Eu costumo imprimir relatórios de progresso no stderr para scripts longos.
terdon

Respostas:

12

Quando estou escrevendo scripts de shell, geralmente acho difícil decidir qual saída e quais mensagens devo apresentar no stderr ou se devo me preocupar.

Silêncio vale ouro. Não produza nada se estiver tudo bem.

Gostaria de saber sobre as boas práticas: quando o redirecionamento de alguma mensagem para o stderr é necessário e razoável e quando não?

A maneira mais fácil de separar stderr de stdout: imagine que toda a saída de seus scripts será redirecionada para outro comando via pipe. Nesse caso, você deve manter todas as notificações no stderr, pois essas informações inesperadas no stdout podem interromper a sequência do pipe.

Também às vezes em tubos como este:

command1 | while read line ; do command2 ; done | command3

você precisa passar algo command2para a saída do usuário. A maneira mais fácil sem arquivos temporários é stderr.

pressa
fonte
Obrigado pela idéia "imagine um cachimbo". Às vezes, implanto scripts que nada fazem além de "notificar" ( echoalgumas variáveis ​​mostram o que foi feito, mostram o progresso). Hesito em colocar tudo no stderr, já que essas mensagens de log são todas que o script jamais produzirá. Não tenho certeza de como aplicar a ideia de pipe nessas situações.
MLDs
1
Os programas @glts estão sempre sendo modificados e aprimorados. Embora os scripts mencionados não produzam dados agora, eles podem ser usados ​​mais tarde ou você pode usá-los como ponto de partida para outros scripts que produzem. Se você seguir a convenção para começar, terá muito menos surpresas mais tarde. OTOH, se você quiser salvar a saída em um arquivo, precisará redirecionar o stderr, para que seja uma troca como todo o resto.
21413 Joe
+1 Outra paráfrase: verifique se o stdout está sempre legível por máquina ou pelo menos contém dados textuais úteis em um formato consistente.
tripleee
2

Geralmente, escrevo tudo o que se relaciona à operação do aplicativo stderr, stdouté reservado para dados.

Imagine uma aplicação como cat. Quando você o usa para ler entradas e passá-las para outro aplicativo (via canal), não deseja que a saída seja repleta de mensagens de status.

Tudo o que pode ser interessante para outro aplicativo ou um pós-processador para o meu aplicativo está indo stdout, tudo o que está relacionado apenas à parte interna do meu aplicativo está indo stderr.

Der Hochstapler
fonte
0

Minha preferência pessoal é enviar mensagens de erro e exceções stderre mensagens informativas para stdout. IMO, stderré para todas as exceções e, portanto, a minha convenção.

unxnut
fonte