Cosa fa `kill -0 $ pid` in uno script di shell?


Risposte:


136

l'invio del segnale 0a un dato PIDcontrolla solo se PIDè in esecuzione un processo con il dato e si dispone dell'autorizzazione per inviare un segnale ad esso.

Per ulteriori informazioni, consultare le seguenti manpage:

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

7
La posizione di queste informazioni (se esiste) dipende fortemente dal sistema. Sui recenti sistemi basati su Debian, usa man 2 killinvece.
Todd A. Jacobs,

2
Entrambi man 1 kille ce l' man 2 killavevo sul mio sistema Fedora 20. È difficile da individuare, seppellito in entrambe quelle pagine man.
slm

Oppure fai affidamento sul manuale posix: If sig is 0 (the null signal), error checking is performed but no signal is actually sent. The null signal can be used to check the validity of pid. pubs.opengroup.org/onlinepubs/009695399/functions/kill.html
Thomas Hughes

2
Sento che il comando man 2 killè fuori dal primo emendamento :)
JBaczuk,

126

Questa è una buona domanda perché ...

... può essere difficile trovare documentazione su questo segnale speciale. Nonostante ciò che altri hanno detto, l'unica menzione di questo segnale nei man 1 killsistemi basati su Debian è:

Segnali particolarmente utili includono HUP, INT, KILL, STOP, CONT e 0.

Non particolarmente utile, soprattutto se non sai già cosa fa il segnale. Inoltre non è elencato dall'output di kill -l, quindi non lo saprai a meno che non lo conosci già.

Dove trovarlo documentato

Sui sistemi Debian e Ubuntu, l'output di man 2 killdice, in parte:

Se sig è 0, non viene inviato alcun segnale, ma viene comunque eseguito il controllo degli errori; questo può essere usato per verificare l'esistenza di un ID processo o ID gruppo processo.

A cosa serve

È possibile utilizzare kill -0per verificare se un processo è in esecuzione. Considera questi esempi.

# Kill the process if it exists and accepts signals from
# the current user.
sleep 60 &
pid=$!
kill -0 $pid && kill $pid

# Check if a PID exists. When missing, this should result
# in output similar to:
#    bash: kill: (6228) - No such process
#    Exit status: 1
kill -0 $pid; echo "Exit status: $?"

È inoltre possibile utilizzare kill -0per determinare se l'utente corrente dispone delle autorizzazioni per segnalare un determinato processo. Per esempio:

# See if you have permission to signal the process. If not,
# this should result in output similar to:
#     bash: kill: (15764) - Operation not permitted
#     Exit status: 1
sudo sleep 60 &
kill -0 $!; echo "Exit status: $?"

Su Mac e BSD è anche documentato in kill(2) Ecco lo snippet:The kill() function sends the signal specified by sig to pid, a process or a group of processes. Typically, Sig will be one of the signals specified in sigaction(2). A value of 0, however, will cause error checking to be performed (with no signal being sent). This can be used to check the validity of pid.
lukecampbell

8
Questa dovrebbe essere la risposta accettata. Molto meglio dell'altro. la documentazione sul segnale 0 è difficile da individuare. È sepolto nella killpagina man: "Se sig è 0, non viene inviato alcun segnale, ma viene comunque eseguito il controllo degli errori."
slm

6

Questo comando verifica se il processo con PID in $ pid è attivo.


1
La pagina man dice: "Se sig è 0, allora non viene inviato alcun segnale, ma il controllo degli errori viene comunque eseguito." A quale controllo degli errori ci riferiamo qui?
gjain,

2
-1, poiché $pidpotrebbe essere in esecuzione un processo con PID ma non si dispone dell'autorizzazione per inviare un segnale.
Dwalter,

2
@dwalter: se non hai i permessi otterrai un EPERM. Se non esiste, otterrai un ESRCH. Il kill(1)stamperà un errore diverso per ciascuno. Quindi, puoi dire se il pid è attivo indipendentemente dal fatto che tu abbia o meno le autorizzazioni per inviare segnali. Inoltre, l'uso tipico di kill -0è vedere se il pid è vivo, anche se non è sempre usato correttamente. Direi che questa risposta è corretta (a parte l'ortografia).
Camh,

3
@camh: no il valore di ritorno di kill -0 $pidsarà lo stesso in entrambi i casi. Restituirà 1quindi non si può dire senza analizzare l'uscita di killse il processo è in esecuzione o meno, se non si dispone dell'autorizzazione per inviare un segnale ad esso. EDIT: sì, lo so che viene utilizzato la maggior parte delle volte per verificare se un processo è attivo, ma questo è sbagliato a meno che tu non possa garantire di avere il permesso di inviare il segnale (ad esempio: essere root)
dwalter

2
@dwalter: il mio punto era che la risposta è corretta. Hai provato a essere pedante e fai notare che c'era un altro caso di errore, ma ti sto dicendo che tecnicamente la risposta copre anche quel caso poiché il killbash incorporato (la domanda è taggata bash) genera il tipo di errore su stderr e l'indicazione di un errore nel suo codice di ritorno. Cioè, "Questo comando controlla [se] il processo con PID in $ pid è attivo" è completamente corretto se si interpreta correttamente l'output. [Non avrei commentato se non avessi detto che hai dato -1 alla risposta. Il tuo commento è altrimenti valido].
Cam

6

Kill -0 $ pid è per verificare se il processo con pid è esistente o meno.

Fai attenzione quando usi 'kill -0 $ pid' per controllare l'esistenza del processo perché

  1. Una volta terminato il processo previsto, il suo pid può essere assegnato a un altro processo appena creato. (Quindi non si può essere così sicuri che quel particolare processo sia vivo o meno)

  2. In caso di processo di zombi, per cui il bambino sta aspettando che il genitore chiami l'attesa. Qui contiene $ pid e dà il risultato positivo mentre quel processo non è in esecuzione.


1

Uccidi -0 $ pid usato per verificare se un processo in esecuzione con $ pid è vivo o no. Ma questo può essere complicato, poiché l'ID processo può essere riassegnato, una volta che un processo viene chiuso e viene eseguito un nuovo processo. Si può usare killall -0 per capire se un particolare processo è in esecuzione o meno.


0

L'invio del EXITsegnale o 0a un processo:

  1. Verifica l'esistenza di un processo.
  2. Effettuare vari controlli degli errori sul processo (PID, PGID, ecc ...).
  3. Non invierà alcun risultato a in stdoutcaso di successo.
  4. Invia un messaggio di errore a stderrse qualcosa non va.
  5. Ti dà un falso positivo se il processo è fallito (ad es. Zombie).

Più esplicitamente, una funzione utile per gli script della shell sarebbe:

function isProcess ()
{
    kill -s EXIT $1 2> /dev/null
}

Questo non restituisce alcun testo in stdoutcaso di successo, ma un messaggio di errore in stderrcaso di fallimento (ma ho reindirizzato quel messaggio di errore in /dev/null).

Se sei preoccupato per lo stato del processo defunto / zombi , allora devi usarlo ps, preferibilmente con l' --no-headersinterruttore.

#!/bin/ksh

function trim ()
{
    echo -n "$1" | tr -d [:space:]
}

function getProcessStatus ()
{
    trim $(ps -p $1 -o stat --no-headers)
}

function isZombie ()
{
    typeset processStatus=$(getProcessStatus $1)

    [[ "$processStatus" == "Z" ]]
    return $?
}
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.