Di recente l'ho trovato in uno script di shell.
if ! kill -0 $(cat /path/to/file.pid); then
... do something ...
fi
Cosa fa kill -0 ...
?
kill -0 $pid
in uno script di shell? e cosa fa effettivamente kill 0? .
Di recente l'ho trovato in uno script di shell.
if ! kill -0 $(cat /path/to/file.pid); then
... do something ...
fi
Cosa fa kill -0 ...
?
kill -0 $pid
in uno script di shell? e cosa fa effettivamente kill 0? .
Risposte:
Questo è un po 'difficile da capire ma se guardi nelle seguenti 2 pagine man vedrai le seguenti note:
uccidere (1)$ man 1 kill
...
If sig is 0, then no signal is sent, but error checking is still performed.
...
uccidere (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.
...
Quindi il segnale 0 in realtà non invierà nulla al PID del processo, ma controllerà se si dispone delle autorizzazioni per farlo.
Un posto ovvio sarebbe se stessi cercando di determinare se disponi delle autorizzazioni per inviare segnali a un processo in esecuzione tramite kill
. È possibile verificare prima di inviare il kill
segnale effettivo desiderato, avvolgendo un controllo per assicurarsi che sia kill -0 <PID>
stato consentito per la prima volta.
Supponiamo che un processo sia stato eseguito da root come segue:
$ sudo sleep 2500 &
[1] 15693
Ora in un'altra finestra se eseguiamo questo comando possiamo confermare che il PID è in esecuzione.
$ pgrep sleep
15693
Ora proviamo questo comando per vedere se abbiamo accesso per inviare i segnali PID tramite kill
.
$ if ! kill -0 $(pgrep sleep); then echo "You're weak!"; fi
bash: kill: (15693) - Operation not permitted
You're weak!
Quindi funziona, ma l'output sta perdendo un messaggio dal kill
comando che non abbiamo autorizzazioni. Non è un grosso problema, basta catturare STDERR e inviarlo a /dev/null
.
$ if ! kill -0 $(pgrep sleep) 2>/dev/null; then echo "You're weak!"; fi
You're weak!
Quindi potremmo fare qualcosa del genere 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
Ora, quando eseguo quanto sopra come utente non root:
$ ~/killer.bash
you don't have permissions to kill PID:15693
$ echo $?
1
Tuttavia, quando viene eseguito come root:
$ sudo ~/killer.bash
$ echo $?
0
$ pgrep sleep
$
pgrep
, ps
analizzare o utilizzare test -e /proc/$PID
script portatili, ma kill -0
funziona ovunque. Se ti viene dato un PID che potrebbe essere obsoleto, ad esempio una /var/run
voce, questo è il modo portatile per verificare se il processo è ancora attivo.
kill -0 $(pgrep sleep)
potrebbe non necessariamente significare che sei debole , restituirà falso se non c'è alcun sleep
comando in esecuzione, o se ce n'è più di uno e ce n'è uno che non puoi uccidere, o se uno dei dormi muore tra il pgrep e il kill comandi in esecuzione.
kill -0
(o la sua variante POSIX più portatile kill -s 0
) passa attraverso il movimento di invio di un segnale, ma in realtà non lo invia. È una caratteristica dell'API C sottostante che il comando shell espone in modo semplice.
kill -s 0 -- "$pid"
verifica quindi se esiste un processo in esecuzione con il PID specificato (o PGID se $pid
è negativo) e se il processo corrente avrebbe l'autorizzazione a inviare $pid
un segnale a uno qualsiasi dei processi nel gruppo di processi in caso di negativo . È principalmente un modo per testare se un processo (o un gruppo di processi) è vivo.
Tieni presente che anche se è in esecuzione un processo con PID e autorizzazioni previsti, questo non è necessariamente il processo che ti aspetti. È possibile che il processo che ti aspetti sia morto prima e che il suo PID sia stato riutilizzato per un processo non correlato. Il modo giusto per monitorare i processi è lasciare che i loro genitori lo facciano - il PID di un processo non viene riutilizzato fino a quando il suo genitore non ha riconosciuto la sua morte (ecco perché esistono gli zombi ), quindi il genitore di un processo può identificare in modo affidabile i suoi figli dal loro PID.
Il kill -0 $pid
ti dice se un processo con $pid
esiste.
Nello snippet
if ! kill -0 $(cat /path/to/file.pid); then
... do something ...
fi
il blocco ... do something ...
viene eseguito se un processo con il PID in cui è memorizzato /path/to/file.pid
è in esecuzione - e - a meno che lo snippet non venga eseguito come root - se il PID viene eseguito con lo stesso utente.
Lo standard POSIX specifica il ruolo del 0
segnale:
Se sig è 0 (segnale nullo), viene eseguito il controllo degli errori ma non viene inviato alcun segnale. Il segnale null può essere utilizzato per verificare la validità di pid.
(kill (3p), POSIX.1-2008 - testo simile in POSIX.1-2001)
Si noti che POSIX specifica sia kill -0
e kill -s 0
stili di linea di comando (kill (1p)).
A differenza dell'interfaccia kill syscall, il kill
comando non può essere utilizzato per verificare in modo affidabile l'esistenza di PID di proprietà di altri utenti (come utente normale), ad esempio:
$ 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
Quando si chiama kill syscall è possibile distinguere in modo affidabile questi casi osservando il errno
valore (vedi ad esempio un esempio Python ).
trap
comando di Bash e 0 rispetto a un segnale 0 dakill
: Qual è il segnale 0 in un comando trap?