O número passado para a chamada de sistema _exit()
/ exit_group()
(às vezes referida como o código de saída para evitar a ambiguidade com status de saída que também está se referindo a uma codificação do código de saída ou do número de sinal e informações adicionais, dependendo se o processo foi morto ou saiu normalmente) é do tipo int
, portanto em sistemas semelhantes ao Unix como o Linux, geralmente um inteiro de 32 bits com valores de -2147483648 ( -2 31 ) para 2147483647 (2 31 -1).
No entanto, em todos os sistemas, quando o processo pai (ou o subagrupador filho ou init
se o pai morreu) usa as chamadas de sistema wait()
, waitpid()
, wait3()
, wait4()
para recuperá-lo, apenas os 8 bits inferiores estão disponíveis (valores de 0 a 255 (2 8 -1)).
Ao usar a waitid()
API (ou um manipulador de sinal no SIGCHLD), na maioria dos sistemas (e como POSIX agora mais requer claramente na edição de 2016 do padrão (consulte _exit()
specification ) ), o número completo está disponível (no campo si_status
da estrutura retornada). Esse não é o caso no Linux, embora também trunque o número para 8 bits com a API waitid()
, embora seja provável que mude no futuro.
Geralmente, você desejaria usar somente valores 0 (geralmente significa sucesso) para 125 apenas, pois muitos shells usam valores acima de 128 em sua representação $?
do status de saída para codificar o número de sinal de um processo sendo morto e 126 e 127 para condições especiais.
Você pode querer usar 126 a 255 em exit()
para significar a mesma coisa que para o $?
do shell (como quando um script faz ret=$?; ...; exit "$ret"
). Usando valores fora de 0 - > 255 geralmente não é útil. Em geral, você só faria isso se soubesse que o pai usará a waitid()
API em sistemas que não truncam e, por acaso, você precisa do intervalo de 32 bits. Observe que, se você fizer um exit(2048)
, por exemplo, isso será visto como um sucesso pelos pais que usam as tradicionais wait*()
APIs.
Mais informações em:
O Q & A deve responder à maioria das suas outras perguntas e esclarecer o que significa status de saída . Vou adicionar mais algumas coisas:
Um processo não pode terminar a menos que seja eliminado ou chama as chamadas do sistema _exit()
/ exit_group()
. Quando você retorna de main()
em C
, a libc chama essa chamada de sistema com o valor de retorno.
A maioria dos idiomas tem uma função exit()
que envolve essa chamada de sistema e o valor que eles recebem, se houver, geralmente é passado como é para a chamada do sistema. (note que esses geralmente fazem mais coisas como a limpeza feita pela função exit()
do C que libera os buffers stdio, executa os atexit()
hooks ...)
Esse é o caso de pelo menos:
$ strace -e exit_group awk 'BEGIN{exit(1234)}'
exit_group(1234) = ?
$ strace -e exit_group mawk 'BEGIN{exit(1234)}'
exit_group(1234) = ?
$ strace -e exit_group busybox awk 'BEGIN{exit(1234)}'
exit_group(1234) = ?
$ echo | strace -e exit_group sed 'Q1234'
exit_group(1234) = ?
$ strace -e exit_group perl -e 'exit(1234)'
exit_group(1234) = ?
$ strace -e exit_group python -c 'exit(1234)'
exit_group(1234) = ?
$ strace -e exit_group expect -c 'exit 1234'
exit_group(1234) = ?
$ strace -e exit_group php -r 'exit(1234);'
exit_group(1234) = ?
$ strace -e exit_group zsh -c 'exit 1234'
exit_group(1234)
Você ocasionalmente vê alguns que reclamam quando você usa um valor fora de 0-255:
$ echo 'm4exit(1234)' | strace -e exit_group m4
m4:stdin:1: exit status out of range: '1234'
exit_group(1) = ?
Algumas conchas reclamam quando você usa um valor negativo:
$ strace -e exit_group dash -c 'exit -1234'
dash: 1: exit: Illegal number: -1234
exit_group(2) = ?
$ strace -e exit_group yash -c 'exit -- -1234'
exit: '-1234' is not a valid integer
exit_group(2) = ?
POSIX deixa o comportamento indefinido se o valor passado para o exit
especial interno estiver fora de 0- > 255.
Alguns shells mostram alguns comportamentos inesperados se você fizer isso:
-
bash
(emksh
mas nãopdksh
no qual é baseado) assume a tarefa de truncar o valor para 8 bits:$ strace -e exit_group bash -c 'exit 1234' exit_group(210) = ?
Então, nesses shells, se você quiser sair com um valor fora de 0-255, terá que fazer algo como:
exec zsh -c 'exit -- -12345' exec perl -e 'exit(-12345)'
Isso é executar outro comando no mesmo processo que pode chamar a chamada do sistema com o valor desejado.
-
como mencionado em outros Q & A,
ksh93
tem o comportamento mais estranho para valores de saída de 257 a 256 + max_signal_number, onde, em vez de chamarexit_group()
, ele se mata com o sinal correspondente¹.$ ksh -c 'exit "$((256 + $(kill -l STOP)))"' zsh: suspended (signal) ksh -c 'exit "$((256 + $(kill -l STOP)))"'
e, caso contrário, trunca o número como
bash
/mksh
.
¹ É provável que mude na próxima versão. Agora que o desenvolvimento de ksh93
foi assumido como um esforço da comunidade fora da AT & T, esse comportamento, embora incentivado de alguma forma, por POSIX, está sendo revertido