Que fait «kill -0 $ pid» dans un script shell?

Réponses:

136

l'envoi du signal 0à un donné PIDvérifie simplement si un processus avec le donné PIDest en cours d'exécution et vous avez la permission de lui envoyer un signal.

Pour plus d'informations, consultez les pages de manuel suivantes:

tuer (1)
$ man 1 kill
...
If sig is 0, then no signal is sent, but error checking is still performed.
...
tuer (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.
...
dwalter
la source
7
L'emplacement de ces informations (le cas échéant) dépend fortement du système. Sur les systèmes récents basés sur Debian, utilisez man 2 killplutôt.
Todd A. Jacobs
2
Les deux man 1 killet l' man 2 killavaient sur mon système Fedora 20. C'est difficile à repérer, enfoui dans ces deux pages de manuel.
slm
Ou 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. utilisez
Thomas Hughes
2
J'ai l'impression que la commande man 2 killest en dehors du 1er amendement :)
JBaczuk
126

C'est une bonne question parce que ...

... il peut être difficile de trouver de la documentation sur ce signal spécial. Malgré ce que d'autres ont dit, la seule mention de ce signal dans les man 1 killsystèmes basés sur Debian est:

Les signaux particulièrement utiles incluent HUP, INT, KILL, STOP, CONT et 0.

Pas particulièrement utile, surtout si vous ne savez pas déjà ce que fait le signal. Il n'est pas non plus répertorié dans la sortie de kill -l, donc vous ne le saurez pas à moins que vous ne le sachiez déjà.

Où le trouver documenté

Sur les systèmes Debian et Ubuntu, la sortie de man 2 killdit, en partie:

Si sig vaut 0, aucun signal n'est envoyé, mais la vérification des erreurs est toujours effectuée; cela peut être utilisé pour vérifier l'existence d'un ID de processus ou d'un ID de groupe de processus.

À quoi ça sert

Vous pouvez utiliser kill -0pour vérifier si un processus est en cours d'exécution. Considérez ces exemples.

# 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: $?"

Vous pouvez également utiliser kill -0pour déterminer si l'utilisateur actuel dispose des autorisations nécessaires pour signaler un processus donné. Par exemple:

# 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: $?"
Todd A. Jacobs
la source
Sur mac et BSD, il est également documenté dans kill(2) Voici l'extrait de 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.
code
8
Cela devrait être la réponse acceptée. Bien mieux que l'autre. la documentation sur le signal 0 est difficile à localiser. Il est enterré dans la killpage de manuel: "Si sig vaut 0, aucun signal n'est envoyé, mais la vérification des erreurs est toujours effectuée."
slm
6

Cette commande vérifie si le processus avec PID dans $ pid est actif.

Fritz G. Mehner
la source
1
La page de manuel indique: "Si sig vaut 0, aucun signal n'est envoyé, mais la vérification des erreurs est toujours effectuée." De quelle vérification d'erreur parlons-nous ici?
gjain
2
-1, car un processus avec PID $pidpeut être en cours d'exécution mais vous n'avez pas l'autorisation de lui envoyer un signal.
dwalter
2
@dwalter: Si vous n'avez pas la permission, vous obtiendrez un EPERM. S'il n'existe pas, vous obtiendrez un ESRCH. Le kill(1)imprimera une erreur différente pour chacun. Ainsi, vous pouvez dire si le pid est actif, que vous ayez ou non l'autorisation d'envoyer des signaux. De plus, l'utilisation typique de kill -0est de voir si le pid est vivant, même s'il n'est pas toujours utilisé correctement. Je dirais que cette réponse est correcte (à part l'orthographe).
camh
3
@camh: non la valeur de retour de kill -0 $pidsera la même dans les deux cas. Il retournera 1donc vous ne pouvez pas dire sans analyser la sortie killsi le processus est en cours d'exécution ou non, si vous n'avez pas l'autorisation de lui envoyer un signal. EDIT: oui je sais qu'il est utilisé la plupart du temps pour vérifier si un processus est en vie, mais c'est faux à moins que vous ne puissiez garantir que vous avez la permission d'envoyer le signal (par exemple: être root)
dwalter
2
@dwalter: Mon point était que la réponse est correcte. Vous avez essayé d'être pédant et de souligner qu'il y avait un autre cas d'erreur, mais je vous dis que techniquement, la réponse couvre ce cas aussi puisque le killbash intégré (la question est étiquetée bash) renvoie le type d'erreur sur stderr, et l'indication d'une erreur dans son code retour. Autrement dit, "Cette commande vérifie [si] le processus avec PID dans $ pid est actif" est tout à fait correct si vous interprétez correctement la sortie. [Je n'aurais pas fait de commentaire si vous n'aviez pas dit que vous aviez donné -1 à la réponse. Votre commentaire est par ailleurs valide].
camh
6

Kill -0 $ pid consiste à vérifier si le processus avec pid existe ou non.

Soyez prudent lorsque vous utilisez 'kill -0 $ pid' pour vérifier l'existence du processus car

  1. Une fois le processus prévu terminé, son pid peut être attribué à un autre processus nouvellement créé. (On ne peut donc pas être si sûr que ce processus particulier est vivant ou non)

  2. Dans le cas du processus Zombie, pour lequel l'enfant attend que le parent appelle, attendez. Ici, il contient le $ pid et donne le résultat positif pendant que le processus n'est pas en cours d'exécution.

Sandeep_black
la source
1

Kill -0 $ pid utilisé pour vérifier si un processus exécuté avec $ pid est actif ou non. Mais cela peut être délicat, car l'ID de processus peut être réaffecté, une fois qu'un processus se termine et qu'un nouveau processus s'exécute. On peut utiliser killall -0 pour se renseigner sur un processus particulier en cours d'exécution ou non.


la source
0

L'envoi du EXITsignal ou 0vers un processus:

  1. Vérifiez l'existence d'un processus.
  2. Effectuez diverses vérifications d'erreurs sur le processus (PID, PGID, etc ...).
  3. Il n'enverra aucune sortie en cas stdoutde succès.
  4. Envoyez un message d'erreur à stderr si quelque chose ne va pas.
  5. Donnez-vous un faux positif si le processus est en panne (par exemple Zombie).

Plus explicitement, une fonction utile pour vos scripts shell serait:

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

Cela ne renvoie aucun texte en cas stdoutde succès, mais un message d'erreur à stderren cas d'échec (mais j'ai redirigé ce message d'erreur vers/dev/null ).

Si vous êtes préoccupé par l'état du processus obsolète / zombie , vous devez utiliser ps, de préférence avec le --no-headerscommutateur.

#!/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 $?
}
Anthony Rutledge
la source