Códigos de Saída Não-Zero Bem Comportados?

1

Entendo que um script de shell shell do UNIX pode, e deve, emitir um código de saída . Um código de saída zero significa que o programa foi concluído com êxito, enquanto um código de saída inteiro positivo (1-255) significa que o programa saiu com um erro.

Faz algum - unix? cartuchos? (não tem certeza sobre a terminologia a usar) -, reservar qualquer um desses 255 códigos de saídas de erro para significados específicos? Ou seja, estou criando um programa de linha de comando que gostaria de ser um cidadão unix bem comportado - posso com segurança fazer com que meu programa retorne qualquer código de saída diferente de zero e que esse código signifique algo para meu programa? Ou existem certos códigos de saída que meu programa não deveria usar, porque o próprio sistema os interpretará de uma maneira particular?

    
por Alan Storm 17.02.2017 / 19:58

1 resposta

3

(EDIT, roubado da resposta, mencionado pelo comentário da pergunta, que, em última análise, apontou aqui ).

Em scripts de shell, status de saída falsos acima de 128 são fornecidos para determinadas condições, portanto, é melhor evitá-los. (O ssh usa 255, que não é usado dessa maneira).

Os dois status de saída abaixo de 128 também são usados para representar certos erros de shell, então você geralmente não quer usar esses códigos também.

BSD passou a tentar padronizar alguns códigos de saída, começando em 64. Eu não vejo nenhum problema em usá-los se você se apaixonar por eles (busca sysexit.h, não é um padrão formal, então você terá para copiá-lo). E se você não estiver usando isso, então "menos de 64" é um número redondo mais agradável do que 126: -P. Dito isto, nem a casca nem o kernel se preocuparão com isso. Eles são usados entre programas de cooperação - especificamente, isso era destinado a componentes de mala direta. Se você quiser mais de 63 "status de erro", eu não me preocupo com esses "reservados" no Unix.

A própria interface de chamada do sistema, também conhecida como kernel, não se importa. Nas chamadas do sistema, os status de saída especiais são codificados fora da banda do 0-255 alcance. É assim que o shell detecta e imprime o status "Killed", para um comando finalizado pelo SIGKILL. Essa informação fora de banda não pode ser falsificada por nenhuma chamada exit simples.

If status is not NULL, wait() and waitpid() store status information in the int to which it points. This integer can be inspected with the following macros (which take the integer itself as an argument, not a pointer to it, as is done in wait() and waitpid()!):

WIFEXITED(status) returns true if the child terminated normally, that is, by calling exit(3) or _exit(2), or by returning from main().

WEXITSTATUS(status) returns the exit status of the child. This consists of the least significant 8 bits of the status argument that the child specified in a call to exit(3) or _exit(2) or as the argument for a return statement in main(). This macro should only be employed if WIFEXITED returned true.

WIFSIGNALED(status) returns true if the child process was terminated by a signal.

WTERMSIG(status) returns the number of the signal that caused the child process to terminate. This macro should only be employed if WIFSIGNALED returned true.

WCOREDUMP(status) returns true if the child produced a core dump. This macro should only be employed if WIFSIGNALED returned true. This macro is not specified in POSIX.1-2001 and is not available on some UNIX implementations (e.g., AIX, SunOS). Only use this enclosed in #ifdef WCOREDUMP ... #endif.

WIFSTOPPED(status) returns true if the child process was stopped by delivery of a signal; this is only possible if the call was done using WUNTRACED or when the child is being traced (see ptrace(2)).

WSTOPSIG(status) returns the number of the signal which caused the child to stop. This macro should only be employed if WIFSTOPPED returned true.

WIFCONTINUED(status) (since Linux 2.6.10) returns true if the child process was resumed by delivery of SIGCONT.

e

ssh exits with the exit status of the remote command or with 255 if an error occurred.

e

$ a
bash: a: command not found...
$ echo $?
127
$ /dev/null
bash: /dev/null: Permission denied
$ echo $?
126
    
por 17.02.2017 / 20:18