Recentemente, deparei com isso em um shell script.
if ! kill -0 $(cat /path/to/file.pid); then
... do something ...
fi
O que kill -0 ...faz?
kill -0 $pidem um script de shell? assim como o que kill 0 realmente faz? .
Recentemente, deparei com isso em um shell script.
if ! kill -0 $(cat /path/to/file.pid); then
... do something ...
fi
O que kill -0 ...faz?
kill -0 $pidem um script de shell? assim como o que kill 0 realmente faz? .
Respostas:
Este é um pouco difícil de entender, mas se você olhar nas duas páginas seguintes, verá as seguintes notas:
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.
...
Portanto, o sinal 0 na verdade não envia nada para o PID do seu processo, mas verifica se você tem permissões para fazê-lo.
Um lugar óbvio seria se você estivesse tentando determinar se tinha permissões para enviar sinais para um processo em execução kill. Você pode verificar antes de enviar o killsinal real que deseja, enviando uma verificação para garantir que kill -0 <PID>foi permitido pela primeira vez.
Digamos que um processo estava sendo executado pela raiz da seguinte maneira:
$ sudo sleep 2500 &
[1] 15693
Agora, em outra janela, se executarmos este comando, podemos confirmar que o PID está sendo executado.
$ pgrep sleep
15693
Agora vamos tentar este comando para ver se temos acesso para enviar esses sinais PID via kill.
$ if ! kill -0 $(pgrep sleep); then echo "You're weak!"; fi
bash: kill: (15693) - Operation not permitted
You're weak!
Portanto, funciona, mas a saída está vazando uma mensagem do killcomando que não temos permissões. Não é grande coisa, basta pegar o STDERR e enviá-lo para /dev/null.
$ if ! kill -0 $(pgrep sleep) 2>/dev/null; then echo "You're weak!"; fi
You're weak!
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 acima como um usuário não root:
$ ~/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
$
pgrep, psanalisar ou test -e /proc/$PIDem scripts portáteis, mas kill -0funciona em qualquer lugar. Se você receber um PID que pode ser obsoleto - por exemplo, uma /var/runentrada -, esta é a maneira portátil de verificar se o processo ainda está ativo.
kill -0 $(pgrep sleep)pode não necessariamente significar que você está fraco , retornará falso se não houver nenhum sleepcomando em execução, ou se houver mais de um e houver um que você não possa matar, ou se um dos dormentes morrer entre o pgrep e o kill comandos sendo executados.
kill -0(ou sua variante POSIX mais portátil kill -s 0) passa pelo movimento de enviar um sinal, mas na verdade não envia um. É um recurso da API C subjacente que o comando shell expõe de maneira direta.
kill -s 0 -- "$pid"assim, testa se existe um processo em execução com o PID especificado (ou PGID, se $pidfor negativo) e se o processo atual teria permissão para enviar $pidum sinal a ele (qualquer um dos processos do grupo de processos em caso de negativo ). É principalmente uma maneira de testar se um processo (ou grupo de processos) está vivo.
Lembre-se de que, mesmo que exista um processo em execução com o PID e as permissões esperados, esse não é necessariamente o processo esperado. É possível que o processo que você espera tenha morrido mais cedo e seu PID tenha sido reutilizado para um processo não relacionado. A maneira correta de monitorar processos é permitir que seus pais o façam - o PID de um processo não é reutilizado até que seu pai reconheça sua morte (é por isso que existem zumbis ), para que o pai de um processo possa identificar seus filhos de maneira confiável por seu PID.
O kill -0 $pidinforma se $pidexiste um processo com .
No trecho
if ! kill -0 $(cat /path/to/file.pid); then
... do something ...
fi
o bloco ... do something ...é executado se um processo com o PID armazenado estiver em /path/to/file.pidexecução - e - a menos que o trecho seja executado como root - se o PID for executado no mesmo usuário.
O padrão POSIX especifica o papel do 0sinal:
Se sig for 0 (o sinal nulo), a verificação de erros será realizada, mas nenhum sinal será realmente enviado. O sinal nulo pode ser usado para verificar a validade do pid.
(kill (3p), POSIX.1-2008 - redação semelhante em POSIX.1-2001)
Observe que o POSIX especifica os estilos de linha de comando kill -0e de kill -s 0comando (kill (1p)).
Ao contrário da interface kill syscall, o killcomando não pode ser usado para verificar com segurança a existência de PIDs pertencentes a outros usuários (como um 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 esses casos de maneira confiável, observando o errnovalor (consulte, por exemplo, um exemplo em Python ).
trapcomando do Bash e 0 vs. um sinal 0 dekill: O que é o sinal 0 em um comando trap?