Considera-se que um processo foi concluído corretamente no Linux se o status de saída for 0.
Vi que falhas de segmentação geralmente resultam em um status de saída 11, embora eu não saiba se essa é simplesmente a convenção em que trabalho (os aplicativos que falharam assim foram todos internos) ou um padrão.
Existem códigos de saída padrão para processos no Linux?
linux
error-handling
exit-code
Nathan Fellman
fonte
fonte
Respostas:
8 bits do código de retorno e 8 bits do número do sinal de extermínio são misturados em um único valor no retorno da
wait(2)
& co. .Como você está determinando o status da saída? Tradicionalmente, o shell armazena apenas um código de retorno de 8 bits, mas define o bit alto se o processo foi finalizado de maneira anormal.
Se você estiver vendo algo diferente disso, provavelmente o programa possui um
SIGSEGV
manipulador de sinal que chamaexit
normalmente, para que não seja realmente morto pelo sinal. (Os programas podem optar por manipular qualquer sinal além deSIGKILL
eSIGSTOP
.)fonte
Parte 1: Guia de script avançado do Bash
Como sempre, o Advanced Bash Scripting Guide possui ótimas informações : (isso foi vinculado em outra resposta, mas a um URL não canônico).
Parte 2: sysexits.h
O ABSG faz referência
sysexits.h
.No Linux:
fonte
man sysexits
sysexits.h
? A página de manual que todo mundo mantém referência é apenas uma prosa. Por exemplo, ele faz referência,EX_OK
mas na verdade não o define de maneira normativa, como os outros códigos. Há mais que estão faltando?'1' >>> Catchall para erros gerais
'2' >>> Uso indevido de componentes internos do shell (de acordo com a documentação do Bash)
'126' >>> O comando invocado não pode ser executado
'127' >>> "comando não encontrado"
'128' >>> Argumento inválido para sair
'128 + n' >>> Sinal de erro fatal "n"
'130' >>> Script finalizado por Control-C
'255' >>> Status de saída fora do intervalo
Isto é para bash. No entanto, para outros aplicativos, existem códigos de saída diferentes.
fonte
Nenhuma das respostas mais antigas descreve o status de saída 2 corretamente. Ao contrário do que eles afirmam, o status 2 é o que seus utilitários de linha de comando realmente retornam quando chamados incorretamente. (Sim, uma resposta pode ter nove anos, ter centenas de votos positivos e ainda estar errada.)
Aqui está a convenção real de status de saída de longa data para terminação normal, ou seja, não por sinal:
Por exemplo,
diff
retorna 0 se os arquivos comparados forem idênticos e 1 se eles diferirem. Por convenção de longa data, programas Unix retornar status de saída 2 quando chamado incorretamente (opções desconhecidos, número errado de argumentos, etc.) Por exemplo,diff -N
,grep -Y
oudiff a b c
tudo vai resultar em$?
ser definido como 2. Este é e tem sido a prática desde o primeiros dias do Unix na década de 1970.A resposta aceita explica o que acontece quando um comando é finalizado por um sinal. Em resumo, a terminação devido a um sinal não capturado resulta no status de saída
128+[<signal number>
. Por exemplo, a terminação porSIGINT
( sinal 2 ) resulta no status de saída 130.Notas
Várias respostas definem o status de saída 2 como "Uso indevido de bash builtins". Isso se aplica somente quando o bash (ou um script do bash) sai com o status 2. Considere-o um caso especial de erro de uso incorreto.
Em
sysexits.h
, mencionado na resposta mais popular , o status de saídaEX_USAGE
("erro de uso da linha de comando") é definido como 64. Mas isso não reflete a realidade: não conheço nenhum utilitário Unix comum que retorne 64 com invocação incorreta (exemplos bem-vindos ) Uma leitura cuidadosa do código fonte revela quesysexits.h
é aspiracional, e não um reflexo do uso real:Em outras palavras, essas definições não refletem a prática comum na época (1993), mas eram intencionalmente incompatíveis com ela. Mais é uma pena.
fonte
more
redefinirá os modos do terminal e sairá com o status 0 (você pode tentar).Não há códigos de saída padrão, além de 0, significando sucesso. Diferente de zero também não significa necessariamente falha.
stdlib.h define
EXIT_FAILURE
como 1 eEXIT_SUCCESS
como 0, mas é isso.O 11 no segfault é interessante, pois 11 é o número do sinal que o kernel usa para interromper o processo no caso de um segfault. Provavelmente, existe algum mecanismo, no kernel ou no shell, que o converte no código de saída.
fonte
sysexits.h tem uma lista de códigos de saída padrão. Parece que remonta a pelo menos 1993 e alguns grandes projetos como o Postfix o usam, então imagino que seja o caminho a seguir.
Na página do manual do OpenBSD:
fonte
Para uma primeira aproximação, 0 é sucesso, diferente de zero é falha, sendo 1 uma falha geral e qualquer coisa maior que uma sendo uma falha específica. Além das exceções triviais de false e test, que são projetadas para fornecer 1 para o sucesso, há outras exceções que encontrei.
Mais realisticamente, 0 significa sucesso ou talvez falha, 1 significa falha geral ou talvez sucesso, 2 significa falha geral se 1 e 0 forem usados para o sucesso, mas talvez também o sucesso.
O comando diff fornece 0 se os arquivos comparados forem idênticos, 1 se eles diferirem e 2 se os binários forem diferentes. 2 também significa falha. O comando less fornece 1 para falha, a menos que você não forneça um argumento; nesse caso, ele sai 0, apesar de falhar.
O comando more e o comando spell fornecem 1 para falha, a menos que a falha seja resultado de permissão negada, arquivo inexistente ou tentativa de ler um diretório. Em qualquer um desses casos, eles saem de 0 apesar de falharem.
Em seguida, o comando expr fornece 1 para sucesso, a menos que a saída seja a sequência vazia ou zero; nesse caso, 0 é sucesso. 2 e 3 são falhas.
Depois, há casos em que o sucesso ou o fracasso é ambíguo. Quando o grep falha em encontrar um padrão, sai 1, mas sai 2 por uma falha genuína (como permissão negada). O Klist também sai do 1 quando falha em encontrar um ticket, embora isso não seja mais uma falha do que quando o grep não encontra um padrão ou quando você está em um diretório vazio.
Portanto, infelizmente, os poderes do unix que parecem existir não impõem nenhum conjunto lógico de regras, mesmo em executáveis muito usados.
fonte
Os programas retornam um código de saída de 16 bits. Se o programa foi interrompido com um sinal, o byte de alta ordem contém o sinal usado; caso contrário, o byte de baixa ordem é o status de saída retornado pelo programador.
Como esse código de saída é atribuído à variável de status $? é então até o shell. O Bash mantém os 7 bits inferiores do status e, em seguida, usa 128 + (sinal nr) para indicar um sinal.
A única convenção "padrão" para programas é 0 para êxito, diferente de zero para erro. Outra convenção usada é retornar errno por erro.
fonte
Os códigos de saída padrão do Unix são definidos por sysexits.h, como outro pôster mencionado. Os mesmos códigos de saída são usados por bibliotecas portáteis como o Poco - aqui está uma lista deles:
http://pocoproject.org/docs/Poco.Util.Application.html#16218
Um sinal 11 é um sinal SIGSEGV (violação de segmento), que é diferente de um código de retorno. Este sinal é gerado pelo kernel em resposta a um acesso incorreto à página, o que faz com que o programa seja encerrado. Uma lista de sinais pode ser encontrada na página de manual do sinal (execute "man signal").
fonte
Quando o Linux retorna 0, significa sucesso. Qualquer outra coisa significa falha, cada programa tem seus próprios códigos de saída, por isso demorou bastante para listá-los todos ...!
Sobre o código de 11 erros, é realmente o número da falha de segmentação, significando principalmente que o programa acessou um local de memória que não foi atribuído.
fonte