Cosa fa `kill -0`?


61

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 ...?


2
Vedi qui se sei confuso sulle differenze tra il trapcomando di Bash e 0 rispetto a un segnale 0 da kill: Qual è il segnale 0 in un comando trap?
slm

Risposte:


76

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.

Dove potrebbe essere utile?

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.

Esempio

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!

Esempio completo

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
$

9
Vorrei anche aggiungere che questo potrebbe essere usato per gli script multi-proc per vedere se un processo è ancora attivo.
prateek61,

1
@slm nice find. Usando questa logica proprio ora in una sceneggiatura che sto scrivendo, grazie.
111 ---

12
Prateek61 ha ragione. Non è possibile utilizzare 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.
Warren Young,

1
Oltre a dirti se il PID è attivo, ti dice anche se sta ancora eseguendo un processo dal tuo UID, poiché non hai l'autorizzazione per inviare segnali ad altri UID (a meno che tu non sia root). Ciò rende meno probabili i falsi positivi dovuti al riutilizzo del PID.
Barmar,

Un fallimento 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.
Stéphane Chazelas,

22

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.


0

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 ).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.