¿Qué hace `kill -0 $ pid` en un script de shell?

Respuestas:

136

enviar la señal 0a un determinado PIDsolo comprueba si se PIDestá ejecutando algún proceso con el dado y usted tiene permiso para enviarle una señal.

Para obtener más información, consulte las siguientes páginas de manual:

matar (1)
$ man 1 kill
...
If sig is 0, then no signal is sent, but error checking is still performed.
...
matar (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
fuente
77
La ubicación de esta información (si es que existe) depende mucho del sistema. En sistemas recientes basados ​​en Debian, use man 2 killen su lugar.
Todd A. Jacobs el
2
Ambos man 1 killy lo man 2 killtenía en mi sistema Fedora 20. Sin embargo, es difícil de detectar, enterrado en ambas páginas de manual.
slm
O confíe en el manual posix en su lugar: 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
Siento que el comando man 2 killestá fuera de la 1ra enmienda :)
JBaczuk
126

Esta es una buena pregunta porque ...

... puede ser difícil encontrar documentación sobre esta señal especial. A pesar de lo que otros han dicho, la única mención de esta señal en los man 1 killsistemas basados ​​en Debian es:

Las señales particularmente útiles incluyen HUP, INT, KILL, STOP, CONT y 0.

No es especialmente útil, especialmente si aún no sabe qué hace la señal. Tampoco está listado por la salida de kill -l, por lo que no lo sabrá a menos que ya lo sepa.

Dónde encontrarlo documentado

En los sistemas Debian y Ubuntu, la salida de man 2 killdice, en parte:

Si sig es 0, entonces no se envía ninguna señal, pero aún se realiza la comprobación de errores; esto se puede usar para verificar la existencia de una ID de proceso o ID de grupo de proceso.

Para qué es bueno

Puede usar kill -0para verificar si un proceso se está ejecutando. Considere estos ejemplos.

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

También puede usar kill -0para determinar si el usuario actual tiene permisos para señalar un proceso determinado. Por ejemplo:

# 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
fuente
En mac y BSD también está documentado en kill(2) Aquí está el fragmento: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 05 de
8
Esta debería ser la respuesta aceptada. Mucho mejor que el otro. La documentación de la señal 0 es difícil de localizar. Está enterrado en la killpágina de manual: "Si sig es 0, entonces no se envía ninguna señal, pero la verificación de errores aún se realiza".
slm
6

Este comando verifica si el proceso con PID en $ pid está vivo.

Fritz G. Mehner
fuente
1
La página de manual dice: "Si sig es 0, entonces no se envía ninguna señal, pero la verificación de errores aún se realiza". ¿A qué comprobación de errores nos referimos aquí?
Gjain
2
-1, ya que $pidpuede estar ejecutándose un proceso con PID pero no tiene permiso para enviarle una señal.
dwalter
2
@dwalter: Si no tiene permiso, obtendrá un EPERM. Si no existe, obtendrá un ESRCH. Se kill(1)imprimirá un error diferente para cada uno. Entonces, puede saber si el pid está vivo independientemente de si tiene permisos para enviar señales o no. Además, el uso típico de kill -0es para ver si el pid está vivo, incluso si no siempre se usa correctamente. Yo diría que esta respuesta es correcta (aparte de la ortografía).
camh
3
@camh: no, el valor de retorno de kill -0 $pidserá el mismo en ambos casos. Volverá, 1por lo que no puede decir sin analizar el resultado de killsi el proceso se está ejecutando o no, si no tiene el permiso para enviarle una señal. EDITAR: sí, sé que se usa la mayor parte del tiempo para verificar si un proceso está vivo, pero esto es incorrecto a menos que pueda garantizar que tiene el permiso para enviar la señal (por ejemplo: ser root)
dwalter
2
@dwalter: Mi punto fue que la respuesta es correcta. Intentó ser pedante y señaló que hubo otro caso de error, pero le digo que técnicamente la respuesta también cubre ese caso, ya que el killbash incorporado (la pregunta está etiquetada bash) muestra el tipo de error en stderr, y la indicación de un error en su código de retorno. Es decir, "Este comando verifica [si] el proceso con PID en $ pid está vivo" es completamente correcto si interpreta la salida correctamente. [No habría comentado si no dijiste que le diste -1 a la respuesta. Su comentario es válido de otra manera].
camh
6

Matar -0 $ pid es para verificar si el proceso con pid existe o no.

Tenga cuidado al usar 'kill -0 $ pid' para verificar la existencia del proceso porque

  1. Una vez que el proceso previsto sale, entonces su pid puede asignarse a otro proceso recién creado. (Por lo tanto, uno no puede estar tan seguro de que un proceso en particular esté vivo o no)

  2. En el caso del proceso Zombie, por el cual el niño está esperando que los padres llamen esperar. Aquí contiene el $ pid y da el resultado positivo mientras ese proceso no se está ejecutando.

Sandeep_black
fuente
1

Matar -0 $ pid se usa para verificar si un proceso que se ejecuta con $ pid está vivo o no. Pero esto puede ser complicado, ya que la ID del proceso se puede reasignar, una vez que sale un proceso y se ejecuta un nuevo proceso. Se puede usar killall -0 para obtener información acerca de que un proceso en particular se está ejecutando o no.


fuente
0

El envío de la EXITseñal o 0a un proceso:

  1. Verifique la existencia de un proceso.
  2. Realice varias comprobaciones de errores en el proceso (PID, PGID, etc.).
  3. No enviará ninguna salida stdoutal éxito.
  4. Enviar un mensaje de error a stderrsi algo no está bien.
  5. Darle un falso positivo si el proceso no funciona (es decir, Zombie).

Más explícitamente, una función útil para sus scripts de shell sería:

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

Esto no devuelve ningún texto stdouten caso de éxito, sino un mensaje de error stderren caso de error (pero he redirigido ese mensaje de error a /dev/null).

Si le preocupa el estado del proceso difunto / zombie , debe usarlo ps, preferiblemente con el --no-headersinterruptor.

#!/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
fuente