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 $pidin 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 $pidin 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 killsegnale 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 killcomando 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, psanalizzare o utilizzare test -e /proc/$PIDscript portatili, ma kill -0funziona ovunque. Se ti viene dato un PID che potrebbe essere obsoleto, ad esempio una /var/runvoce, 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 sleepcomando 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 $pidun 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 $pidti dice se un processo con $pidesiste.
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 0segnale:
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 -0e kill -s 0stili di linea di comando (kill (1p)).
A differenza dell'interfaccia kill syscall, il killcomando 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 errnovalore (vedi ad esempio un esempio Python ).
trapcomando di Bash e 0 rispetto a un segnale 0 dakill: Qual è il segnale 0 in un comando trap?