Como obtenho a lista de códigos de saída (e / ou códigos de retorno) e o significado de um comando / utilitário?

17

Existe uma maneira de fazer o que está indicado no título a partir dos comandos do terminal, ou terei que examinar os códigos?

preciso
fonte

Respostas:

15

Não há "receita" para obter os significados de um status de saída de um determinado comando do terminal.

Minha primeira tentativa seria a página de manual:

user@host:~# man ls 
   Exit status:
       0      if OK,

       1      if minor problems (e.g., cannot access subdirectory),

       2      if serious trouble (e.g., cannot access command-line argument).

Segundo : Google . Veja o wget como um exemplo.

Terceiro : os status de saída do shell, por exemplo, bash. O Bash e seus componentes internos podem usar valores acima de 125 especialmente. 127 para o comando não encontrado, 126 para o comando não executável. Para mais informações, consulte os códigos de saída do bash .

caos
fonte
sim, algum homem, informação, ... páginas as incluem .. e eu estava preocupado com aqueles que não o fizeram. ..e eu sei que uma pesquisa na web é sempre uma opção. ..como para agora parece que foi apenas os códigos de saída do bash que eu tinha que procurar ..
precisa
12

Os códigos de saída indicam uma condição de falha ao finalizar um programa e caem entre 0 e 255. O shell e seus componentes internos podem usar especialmente os valores acima de 125 para indicar modos de falha específicos; portanto, a lista de códigos pode variar entre shells e sistemas operacionais (por exemplo, Bash usa o valor 128 + N como o status de saída). Consulte: Bash - 3.7.5 Status de saída ou man bash.

Em geral, um status de saída zero indica que um comando foi bem-sucedido , um status de saída diferente de zero indica falha .

Para verificar qual código de erro é retornado pelo comando, você pode imprimir $?o último código de saída ou ${PIPESTATUS[@]}qual fornece uma lista de valores de status de saída do pipeline (no Bash) após a saída de um script de shell.

Não há uma lista completa de todos os códigos de saída que podem ser encontrados, no entanto, houve uma tentativa de sistematizar os números de status de saída na fonte do kernel, mas isso é principalmente destinado aos programadores de C / C ++ e pode ser apropriado um padrão semelhante para scripts.

Alguma lista de sysexits no Linux e no BSD / OS X com códigos de saída preferenciais para programas (64-78) pode ser encontrada em /usr/include/sysexits.h(ou: man sysexitsno BSD):

0   /* successful termination */
64  /* base value for error messages */
64  /* command line usage error */
65  /* data format error */
66  /* cannot open input */
67  /* addressee unknown */
68  /* host name unknown */
69  /* service unavailable */
70  /* internal software error */
71  /* system error (e.g., can't fork) */
72  /* critical OS file missing */
73  /* can't create (user) output file */
74  /* input/output error */
75  /* temp failure; user is invited to retry */
76  /* remote error in protocol */
77  /* permission denied */
78  /* configuration error */
/* maximum listed value */

A lista acima aloca códigos de saída não utilizados anteriormente de 64 a 78. O intervalo de códigos de saída não atribuídos será ainda mais restrito no futuro.

No entanto, os valores acima são usados ​​principalmente no sendmail e usados ​​por praticamente ninguém, portanto, eles não são nada remotamente próximos de um padrão (como apontado pelo @Gilles ).

No shell, o status de saída é o seguinte (com base no Bash):

  • 1- 125- O comando não foi concluído com sucesso. Verifique na página do manual do comando o significado do status, alguns exemplos abaixo:

  • 1 - Catchall para erros gerais

    Erros diversos, como "dividir por zero" e outras operações não permitidas.

    Exemplo:

    $ let "var1 = 1/0"; echo $?
    -bash: let: var1 = 1/0: division by 0 (error token is "0")
    1
    
  • 2 - Uso indevido de componentes internos do shell (de acordo com a documentação do Bash)

    Palavra-chave ou comando ausente ou problema de permissão (e código de retorno diff em uma comparação de arquivo binário com falha).

    Exemplo:

     empty_function() {}
    
  • 6 - Esse dispositivo ou endereço não existe

    Exemplo:

    $ curl foo; echo $?
    curl: (6) Could not resolve host: foo
    6
    
  • 124 - tempo limite do comando

  • 125- se um comando falhar, veja: coreutils
  • 126 - se o comando for encontrado, mas não puder ser chamado (por exemplo, não é executável)

    Problema ou comando de permissão não é um executável.

    Exemplo:

    $ /dev/null
    $ /etc/hosts; echo $?
    -bash: /etc/hosts: Permission denied
    126
    
  • 127 - se um comando não puder ser encontrado, o processo filho criado para executá-lo retornará esse status

    Possível problema $PATHou erro de digitação.

    Exemplo:

    $ foo; echo $?
    -bash: foo: command not found
    127
    
  • 128 - Argumento inválido para exit

    exit usa apenas argumentos inteiros no intervalo de 0 a 255.

    Exemplo:

    $ exit 3.14159
    -bash: exit: 3.14159: numeric argument required
    
  • 128- 254- sinal de erro fatal "n" - o comando morreu devido ao recebimento de um sinal. O código do sinal é adicionado a 128 (128 + SIGNAL) para obter o status (Linux man 7 signal:, BSD:) man signal, alguns exemplos abaixo:

  • 130 - comando finalizado devido à pressão do Ctrl-C, 130-128 = 2 (SIGINT)

    Exemplo:

    $ cat
    ^C
    $ echo $?
    130
    
  • 137- se o comando receber o KILL(9)sinal (128 + 9), o status de saída do comando, caso contrário

    kill -9 $PPID de script.

  • 141- SIGPIPE- escreva em um tubo sem leitor

    Exemplo:

    $ hexdump -n100000 /dev/urandom | tee &>/dev/null >(cat > file1.txt) >(cat > file2.txt) >(cat > file3.txt) >(cat > file4.txt) >(cat > file5.txt)
    $ find . -name '*.txt' -print0 | xargs -r0 cat | tee &>/dev/null >(head /dev/stdin > head.out) >(tail /dev/stdin > tail.out)
    xargs: cat: terminated by signal 13
    $ echo ${PIPESTATUS[@]}
    0 125 141
    
  • 143 - comando terminado pelo código de sinal 15 (128 + 15 = 143)

    Exemplo:

    $ sleep 5 && killall sleep &
    [1] 19891
    $ sleep 100; echo $?
    Terminated: 15
    143
    
  • 255* - sai do status fora da faixa.

    exit usa apenas argumentos inteiros no intervalo de 0 a 255.

    Exemplo:

    $ sh -c 'exit 3.14159'; echo $?
    sh: line 0: exit: 3.14159: numeric argument required
    255
    

De acordo com a tabela acima, os códigos de saída 1 - 2, 126 - 165 e 255 têm significados especiais e, portanto, devem ser evitados para os parâmetros de saída especificados pelo usuário.

Observe que os valores de saída fora da faixa podem resultar em códigos de saída inesperados (por exemplo, a saída 3809 fornece um código de saída 225, 3809% 256 = 225).

Vejo:

kenorb
fonte
errnoos valores são usados ​​pelas APIs do sistema, não são usados ​​como status de saída (nem estão no intervalo certo) e são irrelevantes para scripts de shell. Os valores do Sysexits são do sendmail e usados ​​por praticamente ninguém, eles não são nada remotamente próximos de um padrão.
Gilles 'SO- stop be evil'
7

Você precisará examinar o código / documentação. No entanto, o que mais se aproxima de uma "padronização" é errno.h

Thorsten Staerk
fonte
obrigado por mostrar o arquivo de cabeçalho .. tentei olhar para a documentação de alguns utils .. dificuldade em encontrar os códigos de saída, parece mais serão os stderrs ...
preciso
3
errno.hé irrelevante quando se trata de códigos de saída, apenas mensagens de erro.
Gilles 'SO- stop be evil'
A maioria dos programas retorna códigos de saída de acordo com a convenção BSD, conforme descrito em sysexits.h. No entanto, alguns programas retornam errnos, e acho que retornar errnos faz mais sentido. Os errnos não manipulados propagam-se para cima, como exceções (as errnopermanências, funções retornam, por exemplo, -1ou 0|NULL). Como os programas são apenas funções, embora sejam executadas em um espaço de endereço separado, faz sentido que um programa possa desejar continuar a errnopropagação através do limite do processo.
PSKocik
@PSkocik, você tem um exemplo desse comando? errnos não são portáteis (valores não consistentes entre os sistemas) e não há uma maneira portátil de obter o nome ou a mensagem do erro a partir do valor (o zsh possui um builtin para isso). Sem mencionar que alguns sistemas têm erros acima de 123 que colidiriam com códigos de erro comuns de significado especial . Geralmente, os comandos imprimem as mensagens do erro e retornam um status de saída com êxito / falha. comandos são destinados a usuários. chamadas de funções / sistema são destinadas a programadores.
Stéphane Chazelas
@ StéphaneChazelas Eu já vi isso algumas vezes, mas não em nenhum programa bem estabelecido, tenho que admitir. Ultimamente, tenho retornado pessoalmente o errno + 1 no meu sistema de brinquedos (para que 1 continue a significar "qualquer erro") porque acho que serializar errno através do limite do processo faz mais sentido do que traduzir de acordo com a convenção BSD, pois as execuções de programas são essencialmente invocações de funções e funções usam errno. Eu uso meu próprio decodificador last-exit-status no meu PROMPT_COMMAND (bash) para obter algo parecido "($numeric_code|$bsd_decoded|$errno_plus_one_decoded)".
PSKocik
1

Até onde eu sei, existem apenas dois valores padrão, mais ou menos, ambos definidos em stdlib.hpara uso com exit ():

  • EXIT_SUCCESS (= 0)
  • EXIT_FAILURE (= 1)

E o único valor padrão de fato, ou seja, tendo o mesmo significado para todos os programas do mundo, é 0 (zero), que significa SUCESSO.

Programas diferentes introduzem listas diferentes de códigos de "falha" retornados para distinguir ou enfatizar erros diferentes (tipos ou gravidade diferentes). Alguns programas até usam o valor retornado para relatar o número inteiro de erros de tempo de execução descobertos (por exemplo, o número de testes de unidade com falha no processo).

Eu não recomendaria introduzir nenhum tipo de "novo padrão" estendendo o stdlib.h

xoiss
fonte