O que `kill -0 $ pid` em um script shell faz?

Respostas:

136

o envio do sinal 0para um determinado PIDapenas verifica se algum processo com o dado PIDestá em execução e você tem permissão para enviar um sinal para ele.

Para mais informações, consulte as seguintes páginas de manual:

abate (1)
$ man 1 kill
...
If sig is 0, then no signal is sent, but error checking is still performed.
...
abate (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.
...
dwalter
fonte
7
A localização dessas informações (se houver) é altamente dependente do sistema. Em sistemas recentes baseados no Debian, use em seu man 2 killlugar.
Todd A. Jacobs
2
Ambos man 1 kille man 2 killtinha no meu sistema Fedora 20. É difícil identificar, porém, enterrado nas duas páginas de manual.
SLM
Ou então, confie no manual posix: 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. pubs.opengroup.org/onlinepubs/009695399/functions/kill.html
Thomas Hughes
2
Eu sinto que o comando man 2 killestá fora do primeiro alteração :)
JBaczuk
126

Esta é uma boa pergunta porque ...

... pode ser difícil encontrar documentação sobre este sinal especial. Apesar do que outros disseram, a única menção desse sinal nos man 1 killsistemas baseados no Debian é:

Sinais particularmente úteis incluem HUP, INT, KILL, STOP, CONT e 0.

Não é especialmente útil, especialmente se você ainda não sabe o que o sinal faz. Também não é listado pela saída de kill -l, portanto, você não saberá a menos que já saiba.

Onde encontrar documentado

Nos sistemas Debian e Ubuntu, a saída de man 2 kill diz, em parte:

Se sig for 0, nenhum sinal será enviado, mas a verificação de erros ainda será realizada; isso pode ser usado para verificar a existência de um ID do processo ou do grupo de processos.

Para que é bom

Você pode usar kill -0para verificar se um processo está em execução. Considere estes exemplos.

# Kill the process if it exists and accepts signals from
# the current user.
sleep 60 &
pid=$!
kill -0 $pid && kill $pid

# Check if a PID exists. When missing, this should result
# in output similar to:
#    bash: kill: (6228) - No such process
#    Exit status: 1
kill -0 $pid; echo "Exit status: $?"

Você também pode usar kill -0para determinar se o usuário atual tem permissões para sinalizar um determinado processo. Por exemplo:

# See if you have permission to signal the process. If not,
# this should result in output similar to:
#     bash: kill: (15764) - Operation not permitted
#     Exit status: 1
sudo sleep 60 &
kill -0 $!; echo "Exit status: $?"
Todd A. Jacobs
fonte
No Mac e BSD também é documentada no kill(2) Aqui está o trecho:The kill() function sends the signal specified by sig to pid, a process or a group of processes. Typically, Sig will be one of the signals specified in sigaction(2). A value of 0, however, will cause error checking to be performed (with no signal being sent). This can be used to check the validity of pid.
lukecampbell
8
Essa deve ser a resposta aceita. Muito melhor que o outro. a documentação no sinal 0 é difícil de localizar. Ele está oculto na killpágina do manual: "Se sig for 0, nenhum sinal será enviado, mas a verificação de erros ainda será executada."
SLM
6

Este comando verifica se o processo com PID em $ pid está ativo.

Fritz G. Mehner
fonte
1
A página do manual diz: "Se sig for 0, nenhum sinal será enviado, mas a verificação de erros ainda será executada." A que verificação de erro estamos nos referindo aqui?
Gjáin
2
-1, pois um processo com PID $pidpode estar em execução, mas você não tem permissão para enviar um sinal para ele.
dwalter
2
@walter: Se você não tiver permissão, receberá um EPERM. Se não existir, você receberá um ESRCH. O kill(1)imprimirá um erro diferente para cada um. Portanto, você pode saber se o pid está ativo, independentemente de você ter permissões para enviar sinais ou não. Além disso, o uso típico de kill -0é verificar se o pid está vivo, mesmo que nem sempre seja usado corretamente. Eu diria que esta resposta está correta (além da ortografia).
CAMH
3
@ camh: não, o valor de retorno kill -0 $pidserá o mesmo nos dois casos. Ele retornará 1para que você não possa dizer sem analisar a saída de killse o processo está em execução ou não, se você não tiver permissão para enviar um sinal para ele. EDIT: sim, eu sei que é usado na maioria das vezes para verificar se um processo está vivo, mas isso é errado a menos que você pode garantir que você tem permissão para enviar o sinal (por exemplo: ser root)
dwalter
2
@walter: Meu argumento era que a resposta está correta. Você tentou ser pedante e apontou que havia outro caso de erro, mas estou lhe dizendo que tecnicamente a resposta também abrange esse caso, já que o killbash embutido (a pergunta está marcada bash) gera o tipo de erro no stderr e indica de um erro no seu código de retorno. Ou seja, "Este comando verifica [se] o processo com o PID em $ pid está ativo" está completamente correto se você interpretar a saída corretamente. [Eu não teria comentado se você não dissesse que deu -1 à resposta. O seu comentário é válido de outra forma].
camh 13/06/12
6

Kill -0 $ pid é verificar se o processo com pid existe ou não.

Tenha cuidado ao usar 'kill -0 $ pid' para verificar a existência do processo, porque

  1. Uma vez que o processo pretendido saia, seu pid poderá ser alocado para outro processo recém-criado. (Portanto, não se pode ter tanta certeza de que um processo específico esteja vivo ou não)

  2. No caso do processo Zombie, pelo qual o filho está esperando o pai chamar a espera. Aqui ele contém o $ pid e fornece o resultado positivo enquanto esse processo não está em execução.

Sandeep_black
fonte
1

Kill -0 $ pid usado para verificar se um processo em execução com $ pid está ativo ou não. Mas isso pode ser complicado, pois o ID do processo pode ser reatribuído, uma vez que um processo saia e um novo processo seja executado. Pode-se usar killall -0 para obter ou não um processo em particular.


fonte
0

O envio do EXITsinal ou 0para um processo irá:

  1. Verifique a existência de um processo.
  2. Faça várias verificações de erros no processo (PID, PGID, etc ...).
  3. Não enviará nenhuma saída para o stdoutsucesso.
  4. Envie uma mensagem de erro para stderr se algo não estiver certo.
  5. Dê um falso positivo se o processo estiver extinto (por exemplo, Zumbi).

Mais explicitamente, uma função útil para seus scripts de shell seria:

function isProcess ()
{
    kill -s EXIT $1 2> /dev/null
}

Isso não retorna nenhum texto para o stdoutêxito, mas uma mensagem de erro para o stderrerro (mas eu redirecionei essa mensagem de erro para/dev/null ).

Se você estiver preocupado com o status do processo extinto / zumbi , precisará usar ps, de preferência com a --no-headersopção.

#!/bin/ksh

function trim ()
{
    echo -n "$1" | tr -d [:space:]
}

function getProcessStatus ()
{
    trim $(ps -p $1 -o stat --no-headers)
}

function isZombie ()
{
    typeset processStatus=$(getProcessStatus $1)

    [[ "$processStatus" == "Z" ]]
    return $?
}
Anthony Rutledge
fonte