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?
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:
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).
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.
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.
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.
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.
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.
set -e
algum lugar.grep
,diff
retorna 1 quando são encontradas diferenças; e> 1 se ocorreu um erro.Depende do que seu ambiente espera.
Meu favorito para a estranheza, da Wikipedia :
fonte
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.
fonte
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.
fonte
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.
fonte
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.
fonte
Um bom exemplo: man sa-update (spamassassin)
CÓDIGOS DE SAÍDA
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.
fonte