Quais são os valores mínimo e máximo dos seguintes códigos de saída no Linux:
- O código de saída retornado de um executável binário (por exemplo: um programa em C).
- O código de saída retornado de um script bash (ao chamar
exit
). - O código de saída retornado de uma função (ao chamar
return
). Eu acho que isso é entre0
e255
.
linux
executable
function
exit-status
user271801
fonte
fonte
return
É, obviamente, um shell embutido.bash
shell. Alguns outros shellszsh
podem retornar qualquer valor assinado de 32 bits como paraexit
. Alguns gostamrc
oues
podem retornar dados de qualquer um dos tipos suportados (escalar ou lista). Consulte as perguntas e respostas vinculadas para obter detalhes.Respostas:
O número passado para a chamada
_exit()
/exit_group()
system (às vezes chamado de código de saída para evitar a ambiguidade com o status de saída), que também se refere a uma codificação do código de saída ou número do sinal e informações adicionais, dependendo se o processo foi encerrado ou encerrado normalmente ) é do tipoint
, portanto, em sistemas do tipo Unix, como o Linux, geralmente um número inteiro de 32 bits com valores de -2147483648 (-2 31 ) a 2147483647 (2 31 -1).No entanto, em todos os sistemas, quando o processo pai (ou a subreaper criança ou
init
se o pai morreu) usa oswait()
,waitpid()
,wait3()
,wait4()
chamadas de sistema para recuperá-lo, apenas os 8 bits inferiores de que sã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 o POSIX agora exige mais claramente na edição de 2016 do padrão (consulte a_exit()
especificação )), o número completo está disponível (nosi_status
campo da estrutura retornada ) Esse ainda não é o caso do Linux, embora também trunque o número de 8 bits com awaitid()
API, mas isso provavelmente mudará no futuro.Geralmente, você deseja usar apenas os valores 0 (geralmente significando sucesso) a 125 apenas, pois muitos shells usam valores acima de 128 na
$?
representação do status de saída para codificar o número do sinal de um processo que está sendo morto e 126 e 127 para funções especiais. condições.Você pode usar 126 a 255
exit()
para significar a mesma coisa que eles fazem para os shell$?
(como quando um script fazret=$?; ...; exit "$ret"
). Usar valores fora de 0 -> 255 geralmente não é útil. Geralmente, você faria isso apenas se souber que o pai usará awaitid()
API em sistemas que não são truncados e se você precisar do intervalo de valores de 32 bits. Observe que, se você fizer um,exit(2048)
por exemplo, isso será visto como sucesso pelos pais usando aswait*()
APIs tradicionais .Mais informações em:
Esperamos que as perguntas e respostas respondam à maioria das outras perguntas e esclareçam o significado de status de saída . Vou adicionar mais algumas coisas:
Um processo não pode terminar, a menos que seja morto ou faça as chamadas
_exit()
/exit_group()
system. Quando você retorna demain()
inC
, a libc chama essa chamada de sistema com o valor de retorno.A maioria dos idiomas possui uma
exit()
função que agrupa a chamada do sistema e o valor que eles assumem, se algum for geralmente passado como é para a chamada do sistema. (observe que geralmente fazem mais coisas como a limpeza feita pelaexit()
função de C que libera os buffers stdio, executa osatexit()
ganchos ...)Esse é o caso de pelo menos:
Ocasionalmente, você vê algumas reclamações quando usa um valor fora de 0 a 255:
Algumas conchas reclamam quando você usa um valor negativo:
O POSIX deixa o comportamento indefinido se o valor passado para o
exit
built-in especial estiver fora de 0-> 255.Algumas conchas mostram comportamentos inesperados se você:
bash
(emksh
nãopdksh
no qual se baseia) se encarrega de truncar o valor para 8 bits:Portanto, nessas shells, se você quiser sair com um valor fora de 0-255, precisará fazer algo como:
Ou seja, execute outro comando no mesmo processo que pode chamar a chamada do sistema com o valor desejado.
como mencionado nas outras perguntas e respostas,
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¹.e trunca o número como
bash
/mksh
.É provável que isso mude na próxima versão. Agora que o desenvolvimento
ksh93
foi retomado como um esforço da comunidade fora da AT&T, esse comportamento, embora encorajado de alguma forma pelo POSIX, está sendo revertidofonte
si_status
Linux?int
pelo menos 16 bits, o POSIX exige mais ou menos 32 bits e os ambientes de programação possuem um uint32_t . Não sei se o Linux suporta qualquer ambiente de programação em que ints tenham nada além de 32 bits, nunca encontrei nenhum.O mínimo é
0
, e isso é considerado o valor do sucesso. Todos os outros são fracassos. O máximo255
também é conhecido como-1
.Essas regras se aplicam a scripts e outros executáveis, além de funções de shell.
Valores maiores resultam no módulo 256.
fonte
bash
ou outros mais usados) o código de saída passado para oexit
built-in não é tratado como módulo-256 e, em vez disso, causa um erro. (Por exemplo, o comumexit -1
na verdade não é um equivalente portátilexit 255
na maioria das conchas). E seexit(-1)
o nível C é equivalente aexit(255)
um detalhe que certamente funcionará, mas depende do comportamento definido pela implementação (embora isso não seja um problema nos sistemas modernos que você provavelmente utilizará na prática).exit(1)
parâmetro a 8 bits.Isso parece tão simples, mas, oh, os problemas.
A linguagem C (e a seguir à maioria das outras linguagens, direta ou indiretamente) exige que retornar de
main
seja equivalente a chamarexit
com o mesmo argumento que o valor de retorno. Este é um número inteiro (o tipo de retorno é muito claramenteint
), de modo que, em princípio, a gama seriaINT_MIN
deINT_MAX
.No entanto, o POSIX afirma que apenas os 8 bits mais baixos passados
exit
devem ser disponibilizados para um processo pai em espera, literalmente como se fosse "status & 0xFF" .Portanto, na prática, o código de saída é um número inteiro (ainda assinado) do qual apenas os 8 bits mais baixos são definidos.
O mínimo será assim -128 e o máximo 127. Espere, isso não é verdade. Será de 0 a 255.Mas, infelizmente, é claro que não pode ser assim tão simples . Na prática, o Linux (ou melhor, o bash) faz diferente . O intervalo válido de códigos de retorno é de 0 a 255 (isto é, não assinado).
Para estar do lado seguro em termos de evitar confusão, provavelmente é uma boa idéia apenas supor que os códigos de retorno não tenham sinal e transmitir tudo do que você voltar
wait
para não assinado. Dessa forma, é consistente com o que você vê em uma concha. Como os bits mais altos (incluindo o mais significativo) são limpos, isso nem é "errado" porque, embora tecnicamente assinado, os valores reais sempre são sem sinal (pois o bit de sinal nunca é definido).Também ajuda a evitar o erro comum de comparar um código de saída
-1
, o qual, por algum motivo estranho, parece nunca aparecer mesmo quando um programa sai com-1
(bem, adivinhe por que!).Sobre o seu último ponto, retornando de uma função, se essa função acontecer
main
, veja acima. Caso contrário, depende do tipo de retorno da função, poderia, em princípio, ser qualquer coisa (inclusivevoid
).fonte
waitid()
foi introduzido.waitid()
faz exatamente a mesma coisa, um pouco diferente. Ele espera por um ID específico ou por qualquer encadeamento e grava os resultados nasiginfo_t
estrutura apontada para ondesi_status
estáint
(assim ... assinado , da mesma forma). Ainda assim,exit()
só passa os 8 bits mais baixos, então ... absolutamente a mesma coisa sob o capô.exit()
passa todos os 32 bits do parâmetro para o kernel ewaitid()
retorna todos os 32 bits do código de saída. Talvez você tenha verificado no Linux, onde ninguém se importa em corrigir bugs. Se você não acredita em mim, verificá-lo em um complient OS POSIX ...exit
, em particular a segunda linha em "Descrição", que afirma: "embora apenas os 8 bits menos significativos (ou seja, status & 0377) estejam disponíveis para um processo pai em espera " . É assim que uma implementação em conformidade funciona - 8 bits mais baixos, não 32. Você tem uma referência para 32 bits sendo transmitidos?waitid()
e asiginfo_t
estrutura passada aoSIGCHLD
retorno do manipulador todos os 32 bits doexit()
parâmetroOs códigos de saída de qualquer processo - seja um executável binário, um script de shell ou qualquer outra coisa - variam de 0 a 255. É possível passar um valor maior para
exit()
, mas apenas os 8 bits inferiores do status são disponibilizados para outros processos atravéswait()
.A função CA pode ser declarada como retornando quase qualquer tipo. Os limites de seu valor de retorno são determinados inteiramente por esse tipo: por exemplo, -128 a 127 para uma função retornando
signed char
, ou 0 a 4,2 bilhões para uma função retornandounsigned int
, ou qualquer número de ponto flutuante até e inclusiveinf
para uma função retornandodouble
. E isso não está contando os tipos não numéricos, comovoid *
ou umstruct
...fonte