Por que é “while kill -0 $ PID” e não “until kill -0 $ PID”?

6

Eu posso estar sendo maluco aqui, mas se eu quiser fazer algo enquanto um processo está em andamento, por que eu faço:

while kill -0 $PID
do
    #...
done

em vez de

until kill -0 $PID
do
    #...
done

?

kill -0 sai com o código 1 se o processo não for encontrado e 0 se o processo for encontrado:

$ kill -0 123444
-bash: kill: (123444) - No such process
$ echo $?
1
$ screen -ls | grep rofl
    28043.rofl  (02/19/2015 02:27:56 PM)    (Detached)
$ kill -0 28043
$ echo $?
0

Portanto, se o processo estiver em execução, o loop while não se resumirá a:

while 0
do
    #...
done

que nunca seria executado?

    
por Claudiu 19.02.2015 / 20:31

4 respostas

7

Ao lidar com códigos de retorno, "0" é um sucesso e não-zero é uma falha. A sintaxe de um loop while é:

while COMMANDS; do ...; done

A instrução while verifica o código de retorno do último comando na lista de comandos fornecida. Em seu último exemplo de while 0 , isso tentará executar um comando chamado "0" e verificar seu código de retorno.

Um literal 0 não é especial para basear fora do contexto aritmético. Dentro desse contexto, 0 é considerado falso. Por exemplo

while (( 0 )); do
  ... # never executes
end

Este caso é especial, pois a palavra-chave (( é tratada como um comando, que retorna diferente de zero porque o resultado é 0.

    
por 19.02.2015 / 20:56
5

O shell não expande a condição como você pensa.

No shell, um código de erro 0 indicou que o comando foi concluído com êxito. Qualquer código de erro diferente de zero indicou que houve erro.

Para mais conciso, o POSIX define o loop como:

The while loop shall continuously execute one compound-list as long as another compound-list has a zero exit status.

The format of the while loop is as follows:

while compound-list-1
do
    compound-list-2
done

The compound-list-1 shall be executed, and if it has a non-zero exit status, the while command shall complete. Otherwise, the compound-list-2 shall be executed, and the process shall repeat.

    
por 19.02.2015 / 20:52
5

A "enquanto" comando não está à procura de um valor booleano, está à procura de um código de retorno de "0" o que indica execução bem-sucedida do comando. Portanto, no caso do comando while, um comando que retorna 0 é "true" e qualquer outra coisa é "false".

Mesmo quando você está fazendo uma comparação, Bash trata isso como um comando que está retornando um código de erro de sucesso (0) quando a comparação é verdadeira.

    
por 19.02.2015 / 21:01
2

O código de saída não é um valor booleano, é um inteiro, por convenção o valor zero é bem sucedido, então você está pensando na lógica negativa do ponto de vista do Bash

    
por 19.02.2015 / 20:51