Status de saída diferente de zero para saída limpa

15

É aceitável retornar um código de saída diferente de zero se o programa em questão foi executado corretamente? Por exemplo, digamos que eu tenha um programa simples que (somente) faça o seguinte:

Programa recebe N argumentos. Retorna um código de saída min (N, 255). Observe que qualquer N é válido para o programa.

Um programa mais realista pode retornar códigos diferentes para programas executados com sucesso que significam coisas diferentes. Em vez disso, esses programas devem gravar essas informações em um fluxo, como no stdout?

Thomas Eding
fonte

Respostas:

24

Depende do ambiente, mas eu diria que é um estilo pobre.

Os sistemas tipo Unix têm uma convenção forte de que um status de saída 0 indica êxito e qualquer status de saída diferente de zero indica falha. Alguns programas, mas não todos, distinguem entre diferentes tipos de falhas com códigos de saída diferentes de zero; por exemplo, grepnormalmente retorna 0 se o padrão foi encontrado, 1 se não foi e 2 (ou mais) se houve um erro, como um arquivo ausente.

Essa convenção é praticamente conectada às conchas do Unix. Por exemplo, em sh, bashe outros shells semelhantes a Bourne, a ifinstrução trata um status de saída 0 como êxito / verdadeiro e um status de saída diferente de zero como falha / falso:

if your-command
then
    echo ok
else
    echo FAILURE
fi

Eu acredito que as convenções no MS Windows são semelhantes.

Agora certamente não há nada que o impeça de escrever seu próprio programa que usa códigos de saída não convencionais, especialmente se nada mais interagir com ele, mas lembre-se de que você está violando uma convenção bem estabelecida e que pode voltar e mordê-lo mais tarde .

A maneira usual de um programa retornar esse tipo de informação é imprimi-lo em stdout:

status = $(your-command)
echo Result is $status
Keith Thompson
fonte
7
+1 por explicar a convenção, essa abordagem quebraria a maioria dos meus scripts de shell se eu colocasse um em set -ealgum lugar.
Benjamin Bannier
Da mesma forma grep, diffretorna 1 quando são encontradas diferenças; e> 1 se ocorreu um erro.
7heo.tk
6

Depende do que seu ambiente espera.

Meu favorito para a estranheza, da Wikipedia :

No OpenVMS, o sucesso é indicado por valores ímpares e a falha por valores pares. O valor é um número inteiro de 32 bits com subcampos: bits de controle, número da instalação, número da mensagem e gravidade. Os valores de gravidade são divididos entre sucesso (Sucesso, Informativo) e falha (Aviso, Erro, Fatal).

Conta
fonte
4

Eu acho que existe um precedente se o código de saída estiver retornando informações significativas e relevantes para o chamador e a definição de sucesso não for realmente binária. O precedente em que estou pensando é a robocópia, que retorna várias coisas diferentes, dependendo do que aconteceu .

Vou acrescentar que sempre acabamos tendo alguma depuração por causa disso - a maioria dos utilitários assume o código de saída 0 == com êxito, então fique assustada quando a robocopy retornar 1 porque copiou coisas que não eram zero porque não copiavam coisas, mas não ' também não obtém um erro.

Wyatt Barnett
fonte
2

não retornar 0 para uma execução bem-sucedida é uma péssima idéia, pois pode causar confusão para quem está executando seu programa. E se alguns executassem seu programa mais de 100 vezes com entradas diferentes e desejassem saber quantas falhas ou foram concluídas com êxito, ter um único valor de sucesso torna muito mais fácil detectar diferenças do que ter muitos valores diferentes.

Se você tem um programa que possui vários caminhos de retorno bem-sucedidos que podem significar coisas diferentes, eu diria que é um sinal de que seu programa foi mal projetado.

Ryathal
fonte
2

Conheço um caso que considero aceitável. Conheço uma estrutura de teste que sai com o número total de falhas de teste. Portanto, por exemplo, se o executor de teste for concluído sem testes com falha, ele sairá com zero. Se um teste falhar, mesmo que o testador tenha executado propriamente, ele sairá com um 1. Se dois falharem, retornará 2 etc. Isso aumenta para 250, o que significa "250 ou mais falhas no teste".

Ele usa códigos de saída> 250 para indicar saídas anormais.

Embora isso viole as convenções, funciona bem na prática.

Bryan Oakley
fonte
3
Eu não acho que isso faz violar convenções - o teste é bem sucedido se não há erros; qualquer código de resultado diferente de zero indica testes com falha.
Bevan
1
Isso é "sair com um status de erro para indicar mais de 0 erros" e, embora possa violar a semântica comum exata do status de saída, certamente não viola a convenção maior "0 está OK, qualquer coisa maior que 0 é um erro" .
Vatine
2

Realmente depende do que você está tentando transmitir com o código. O DB2, por exemplo, retorna 100 se não houver dados encontrados, vários outros valores positivos para avisos e valores negativos para erros. Oracle faz algo semelhante.

Portanto, se houver diferentes estados de sucesso, pode valer a pena usar valores de retorno variáveis.

Matthew Flynn
fonte
2

Um bom exemplo: man sa-update (spamassassin)

CÓDIGOS DE SAÍDA

  • Um código de saída 0 significa que uma atualização estava disponível e foi baixada e instalada com sucesso se --checkonly não foi especificado.
  • Um código de saída 1 significa que nenhuma atualização nova estava disponível.
  • Um código de saída 2 significa ...

Nesse caso, a saída 1 é simplesmente um código informativo. No entanto, se eu tivesse escrito o código, não teria escolhido 1, pois geralmente falha na rede.

Evert
fonte