O status de saída de um comando é implementado pelo comando ou por um processo shell que executa o comando?

4

Do manual do bash

The exit status of an executed command is the value returned by the waitpid system call or equivalent function. Exit statuses fall between 0 and 255, though, as explained below, the shell may use values above 125 specially. Exit statuses from shell builtins and compound commands are also limited to this range. Under certain circumstances, the shell will use special values to indicate specific failure modes.

  1. O que determina o status de saída de um comando executado,

    • o comando em si ou seja, a implementação do comando determina o status de saída, ou seja, a determinação do status de saída de um comando executado é uma propriedade inerente do comando, assim como a análise dos argumentos da linha de comando para uma execução de um comando é inerente ao comando ou
    • o processo do shell que executou o comando?
      A chamada do sistema waitpid mencionada acima parece-me que a saída O status de um comando executado é implementado pelo processo de shell, e o comando em si não tem nada a ver com o status de saída de uma execução de si mesmo.
  2. Em um processo bash, quando podemos obter o status de saída de uma execução comando,

    • apenas quando o processo bash é interativo ou
    • , independentemente de o processo bash ser interativo ou não interativo? Quando um processo bash não é interativo, como podemos recuperar o status de saída de um comando executado no processo bash?
por Tim 09.12.2016 / 19:19

3 respostas

9

O comando em si pode fornecer o status de saída, por meio do argumento para uma chamada de sistema exit() . O shell (ou outro programa, como sobre system() em Perl ou PHP?) Pode pegar o status de saída de um processo filho através de wait() ou waitpid() chamadas do sistema. Os kernels Unix / Linux / * BSD se organizam para entregar SIGCHLD ao processo pai quando um processo filho muda de status.

Mas há outras circunstâncias. Um processo encerrado via SIGKILL não tem chance de sair. Um processo que não referencia um endereço inválido não terá a chance de chamar exit() a menos que tenha um manipulador de sinais SIGSEGV instalado. Nesses casos, o kernel calcula um status de saída que inclui um bit que significa "morto por um sinal" e qual sinal causou a morte do processo. Esse status de saída calculado pelo kernel é entregue ao processo pai do processo eliminado.

    
por 09.12.2016 / 19:39
5

O código define o status de saída

$ perl -e 'END { $? = 42 }'; echo $?
42
$ 

exceto quando isso não acontece

$ perl -e 'sleep 999; END { $? = 42 }'
^C
$ echo $?
130
$ echo $((130-128))
2
$ kill -l | head -2
 1    HUP Hangup                        17   STOP Stopped (signal)         
 2    INT Interrupt                     18   TSTP Stopped
$ 

ou faz

$ perl -e '$SIG{INT}=sub{exit 7};sleep 999'                   
^C$ echo $?
7
$ 

ou não deve alguém brincalhão com SIGKILL , etc.

Caso contrário, a documentação bash é enganosa, pois waitpid define uma palavra de status de 16 bits, mas bash passa apenas um subconjunto dela na variável $? da shell. Isso pode levar à ignorância e confusão caso um usuário de shell tente lidar com os resultados de waitpid como se fosse um valor de 8 bits (não é).

$ false; echo $?
1
$ perl -E 'system("false"); say $?'
256
$ perl -E 'system("false"); say $? >> 8'
1
$ 
    
por 09.12.2016 / 19:48
2

Um processo determina seu próprio código de saída. Quando termina, fornece o código de saída ou, se nenhum for fornecido, presume-se que seja zero (sem erro).

Com shells interativos e não interativos, o código de saída do comando anterior é obtido através do valor de $? .

    
por 09.12.2016 / 19:31