Quando usar o fluxo de erros padrão no aplicativo de linha de comando?

9

Existe uma diretriz para quando usar o erro ao escrever um aplicativo de linha de comando? Para minha surpresa, não encontrei nada ao pesquisar no Google.

Em particular, a questão que me preocupa agora é se deve usar stdoutou stderrquando o usuário chamou o programa com argumentos ilegais. No entanto, uma resposta mais abrangente é muito apreciada, porque esse certamente não será o único caso em que uma regra clara será necessária para escrever um programa que se comporte da maneira esperada pelo usuário.

UTF-8
fonte
Tudo bem que essas mensagens de erro se misturem com a saída regular? Por exemplo, o programa é um filtro de dados?
thrig
Não é um filtro para dados. Também não é interativo. O usuário chama isso com argumentos (entre os quais os caminhos de arquivo), o programa funciona, altera esses arquivos, imprime algumas mensagens, idealmente não imprime nenhuma mensagem de erro e termina.
UTF-8

Respostas:

15

Sim, exiba uma mensagem stderrquando os argumentos errados forem usados. E se isso também fizer com que o aplicativo saia, saia com um status de saída diferente de zero.

Você deve usar o fluxo de erros padrão para mensagens de diagnóstico ou para interação do usuário. As mensagens de diagnóstico incluem mensagens de erro, avisos e outras mensagens que não fazem parte da saída do utilitário quando estão funcionando corretamente ("corretamente" significa que não há nada de excepcional acontecendo, como arquivos não encontrados ou o que quer que seja).

Muitos shells (todos?) Exibem avisos, o que o usuário digita, menus etc., stderrpara que o redirecionamento stdoutnão o impeça de interagir com o shell de maneira significativa.

O seguinte é de uma postagem de blog sobre este tópico:

Esta é uma citação de Doug McIllroy, inventor de pipes Unix, explicando como stderrsurgiu. 'v6' está se referindo a uma versão da versão específica do sistema operacional Unix original, lançada em 1975.

Todos os programas colocaram diagnósticos na saída padrão. Isso sempre causava problemas quando a saída era redirecionada para um arquivo, mas tornava-se intolerável quando a saída era enviada para um processo desavisado. No entanto, não querendo violar a simplicidade do modelo de entrada-padrão-saída-padrão, as pessoas toleraram esse estado de coisas através da v6. Pouco tempo depois, Dennis Ritchie cortou o nó górdio, introduzindo o arquivo de erro padrão. Isso não foi o bastante. Com os pipelines, o diagnóstico pode vir de qualquer um dos vários programas em execução simultaneamente. Diagnóstico necessário para se identificar.
- Doug McIllroy, "Um leitor UNIX de pesquisa: trechos anotados do manual do programador, 1971-1986"

"Identificar-se" significa simplesmente dizer "Ei! Sou eu falando! Isso deu errado: [...]":

$ ls nothere
ls: nothere: No such file or directory

stderrÉ preferível fazer isso , pois de outra forma poderia ser lido pelo que estava lendo stdout(mas não fazemos isso de lsqualquer maneira , não é?).

Kusalananda
fonte
Então, quando você perguntar algo ao usuário enquanto o aplicativo está sendo executado, você deve imprimir a pergunta no stderr? Isso não parece certo. Você tem uma fonte para isso? Isso se aplica apenas a aplicativos com saída diferente de perguntas e respostas (saída que o usuário pode querer canalizar em algum lugar)?
UTF-8
@ UTF-8 O texto da pergunta deve ser considerado parte da produção do programa? E o que o usuário digita? Eu não acho que deveria ser (assim como conchas não acham que deveria ser). Mas talvez dependa da aplicação?
Kusalananda
1
Obrigado pela sua edição. Enquanto isso, verifiquei o comportamento dos aplicativos padrão e eles se comportam como se esperasse que eles se comportassem depois de ler sua resposta.
UTF-8
@ UTF-8, você pode achar relevante esta sessão de
terdon
5

Das especificações POSIX para os fluxos padrão:

Na inicialização do programa, três fluxos devem ser predefinidos e não precisam ser abertos explicitamente: entrada padrão (para leitura de entrada convencional), saída padrão (para gravação de saída convencional) e erro padrão (para gravação de saída de diagnóstico ).

Em outras palavras, erros, informações de depuração e qualquer coisa que se enquadre na categoria de diagnóstico são inseridos stderr.

Consulte a pergunta relacionada para obter mais informações: Os relatórios de progresso / informações de registro pertencem ao stderr ou stdout?

Sergiy Kolodyazhnyy
fonte