Recientemente me encontré con esto en un script de shell.
if ! kill -0 $(cat /path/to/file.pid); then
... do something ...
fi
¿Qué kill -0 ...
hacer?
kill -0 $pid
en un script de shell? así como ¿Qué hace realmente matar 0? .
Recientemente me encontré con esto en un script de shell.
if ! kill -0 $(cat /path/to/file.pid); then
... do something ...
fi
¿Qué kill -0 ...
hacer?
kill -0 $pid
en un script de shell? así como ¿Qué hace realmente matar 0? .
Respuestas:
Este es un poco difícil de obtener, pero si mira en las siguientes 2 páginas de manual, verá las siguientes notas:
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.
...
Por lo tanto, la señal 0 en realidad no enviará nada al PID de su proceso, pero verificará si tiene permisos para hacerlo.
Un lugar obvio sería si intentara determinar si tenía permisos para enviar señales a un proceso en ejecución kill
. Puede verificar antes de enviar la kill
señal real que desea, envolviendo un cheque para asegurarse de que kill -0 <PID>
primero se permitió.
Digamos que un proceso estaba siendo ejecutado por root de la siguiente manera:
$ sudo sleep 2500 &
[1] 15693
Ahora, en otra ventana, si ejecutamos este comando, podemos confirmar que ese PID se está ejecutando.
$ pgrep sleep
15693
Ahora intentemos este comando para ver si tenemos acceso para enviar esas señales PID a través de kill
.
$ if ! kill -0 $(pgrep sleep); then echo "You're weak!"; fi
bash: kill: (15693) - Operation not permitted
You're weak!
Entonces funciona, pero la salida está filtrando un mensaje del kill
comando de que no tenemos permisos. No es gran cosa, simplemente coge STDERR y envíalo /dev/null
.
$ if ! kill -0 $(pgrep sleep) 2>/dev/null; then echo "You're weak!"; fi
You're weak!
Entonces podríamos hacer algo como esto 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
Ahora cuando ejecuto lo anterior como un usuario no root:
$ ~/killer.bash
you don't have permissions to kill PID:15693
$ echo $?
1
Sin embargo, cuando se ejecuta como root:
$ sudo ~/killer.bash
$ echo $?
0
$ pgrep sleep
$
pgrep
, ps
analizar o test -e /proc/$PID
en scripts portátiles, pero kill -0
funciona en todas partes. Si recibe un PID que puede estar obsoleto, por ejemplo, una /var/run
entrada, esta es la forma portátil de verificar si el proceso aún está activo.
kill -0 $(pgrep sleep)
puede no necesariamente significar que eres débil , devolverá falso si no se está sleep
ejecutando un comando, o si hay más de uno y hay uno que no puedes matar, o si uno de los durmientes muere entre el pgrep y el kill comandos que se ejecutan.
kill -0
(o su variante POSIX más portátil kill -s 0
) pasa por el movimiento de enviar una señal, pero en realidad no envía una. Es una característica de la API de C subyacente que el comando de shell expone de manera directa.
kill -s 0 -- "$pid"
por lo tanto, comprueba si hay un proceso en ejecución con el PID dado (o PGID si $pid
es negativo), y si el proceso actual tendría permiso para enviarle (cualquiera de los procesos en el grupo de procesos en caso de ser negativo $pid
) una señal. Es principalmente una forma de probar si un proceso (o grupo de procesos) está vivo.
Tenga en cuenta que incluso si hay un proceso en ejecución con el PID y los permisos esperados, este no es necesariamente el proceso que espera. Es posible que el proceso que esperas haya muerto antes y que su PID se haya reutilizado para un proceso no relacionado. La forma correcta de monitorear los procesos es dejar que sus padres lo hagan: el PID de un proceso no se reutiliza hasta que su padre haya reconocido su muerte (es por eso que existen zombis ), por lo que el padre de un proceso puede identificar de manera confiable a sus hijos por su PID.
El kill -0 $pid
te dice si $pid
existe un proceso con .
En el fragmento
if ! kill -0 $(cat /path/to/file.pid); then
... do something ...
fi
el bloque ... do something ...
se ejecuta si se está ejecutando un proceso con el PID almacenado /path/to/file.pid
, y, a menos que el fragmento se ejecute como root, si el PID se ejecuta bajo el mismo usuario.
El estándar POSIX especifica el papel de la 0
señal:
Si sig es 0 (la señal nula), se realiza la comprobación de errores pero no se envía ninguna señal. La señal nula se puede utilizar para verificar la validez de pid.
(kill (3p), POSIX.1-2008 - redacción similar en POSIX.1-2001)
Tenga en cuenta que POSIX especifica tanto kill -0
y kill -s 0
estilos de línea de comandos (kill (1p)).
A diferencia de la interfaz kill syscall, el kill
comando no se puede usar para verificar de manera confiable la existencia de PID propiedad de otros usuarios (como usuario normal), por ejemplo:
$ 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
Al llamar al kill syscall, uno puede distinguir de manera confiable estos casos mirando el errno
valor (por ejemplo, un ejemplo de Python ).
trap
comando de Bash y 0 frente a una señal 0 dekill
: ¿Qué es la señal 0 en un comando de captura?