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 $pid
em 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 $pid
em 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 kill
sinal 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 kill
comando 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
, ps
analisar ou test -e /proc/$PID
em scripts portáteis, mas kill -0
funciona em qualquer lugar. Se você receber um PID que pode ser obsoleto - por exemplo, uma /var/run
entrada -, 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 sleep
comando 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 $pid
for negativo) e se o processo atual teria permissão para enviar $pid
um 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 $pid
informa se $pid
existe 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.pid
execuçã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 0
sinal:
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 -0
e de kill -s 0
comando (kill (1p)).
Ao contrário da interface kill syscall, o kill
comando 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 errno
valor (consulte, por exemplo, um exemplo em Python ).
trap
comando do Bash e 0 vs. um sinal 0 dekill
: O que é o sinal 0 em um comando trap?