O que 'kill -0' faz?

53

Recentemente me deparei com isso em um script de shell.

if ! kill -0 $(cat /path/to/file.pid); then
    ... do something ...
fi

O que o kill -0 ... faz?

    
por slm 25.11.2014 / 18:50

3 respostas

71

Este é um pouco difícil de brilhar, mas se você olhar nas duas páginas man seguintes você verá as seguintes notas.

matar (1)
$ man 1 kill
...
If sig is 0, then no signal is sent, but error checking is still performed.
...
matar (2)
$ man 2 kill
...
If sig is 0, then no signal is sent, but error checking is still performed; 
this can be used to check for the existence of a process ID or process 
group ID.
...

Portanto, o sinal 0 não enviará de fato nada para o PID do seu processo, mas verificará se você tem permissão para fazê-lo.

Onde isso pode ser útil?

Um lugar óbvio seria se você estivesse tentando determinar se você tinha permissões para enviar sinais para um processo em execução via kill . Você pode verificar antes de enviar o sinal kill real desejado, colocando uma verificação para garantir que kill -0 <PID> seja permitido pela primeira vez.

Exemplo

Digamos que um processo estava sendo executado pelo root da seguinte forma:

$ sudo sleep 2500 &
[1] 15690

Agora, em outra janela, se executarmos este comando, podemos confirmar que esse PID está sendo executado.

$ pgrep sleep
15693

Agora vamos tentar este comando para ver se temos acesso para enviar os sinais PID via kill .

$ if ! kill -0 $(pgrep sleep); then echo "You're weak!"; fi
bash: kill: (15693) - Operation not permitted
You're weak!

Então funciona, mas a saída está vazando uma mensagem do comando kill que não temos permissões. Não é grande coisa, basta pegar STDERR e enviá-lo para /dev/null .

$ if ! kill -0 $(pgrep sleep) 2>/dev/null; then echo "You're weak!"; fi
You're weak!

Exemplo completo

Então poderíamos fazer algo assim, killer.bash :

#!/bin/bash

PID=$(pgrep sleep)
if ! kill -0 $PID 2>/dev/null; then 
  echo "you don't have permissions to kill PID:$PID"
  exit 1
fi

kill -9 $PID

Agora, quando executo o código acima como um usuário não raiz.

$ ~/killer.bash 
you don't have permissions to kill PID:15693

$ echo $?
1

No entanto, quando é executado como root:     $ sudo ~ / killer.bash

$ echo $?
0

$ pgrep sleep
$
    
por 25.11.2014 / 18:50
19

kill -0 (ou sua variante POSIX kill -s 0 ) passa pelo movimento de enviar um sinal, mas na verdade não envia um. É um recurso da API C subjacente que os shell é exposto de maneira direta.

kill -s 0 -- "$pid" , portanto, testa se há um processo em execução com o PID (ou PGID se $pid é negativo) e se o processo atual teria permissão para enviá-lo (qualquer um dos processos no grupo de processos no caso de um $pid negativo) um sinal. É principalmente uma maneira de testar se um processo (ou grupo de processos) está ativo.

Tenha em mente que, mesmo se houver um processo em execução com o PID e as permissões esperadas, isso não é necessariamente o processo esperado. É possível que o processo que você espera tenha morrido antes e seu PID tenha sido reutilizado para um processo não relacionado. O caminho certo para monitorar processos é deixar o pai fazer isso - o PID de um processo não é reutilizado até que seu pai tenha reconhecido sua morte (é por isso que zumbis existem), portanto, os pais de um processo podem identificar seus filhos de maneira confiável por meio de seu PID.

    
por 26.11.2014 / 02:28
0

O kill -0 $pid informa se existe um processo com $pid .

No snippet

if ! kill -0 $(cat /path/to/file.pid); then
    ... do something ...
fi

o bloco ... do something ... é executado se um processo com o PID armazenado em /path/to/file.pid estiver em execução - e - a menos que o snippet seja executado como raiz - se o PID for executado sob o mesmo usuário.

O padrão POSIX especifica o papel do sinal 0 :

If sig is 0 (the null signal), error checking is performed but no signal is actually sent. The null signal can be used to check the validity of pid.

(kill (3p), POSIX.1-2008 - texto similar em POSIX.1-2001)

Observe que o POSIX especifica os estilos de linha de comando kill -0 e kill -s 0 (kill (1p)).

Em contraste com a interface kill syscall, o comando kill não pode ser usado para verificar de forma confiável a existência de PIDs pertencentes a outros usuários (como usuário normal), por exemplo:

$ kill -0 123
kill: kill 123 failed: no such process
$ echo $?
1

vs.

$ kill -0 1
kill: kill 1 failed: operation not permitted
$ echo $?
1

Ao chamar o kill syscall, é possível distinguir com segurança esses casos, observando o valor errno (por exemplo, um Exemplo do Python ).

    
por 07.02.2018 / 11:13