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 $piden 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 $piden 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 killseñ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 killcomando 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, psanalizar o test -e /proc/$PIDen scripts portátiles, pero kill -0funciona en todas partes. Si recibe un PID que puede estar obsoleto, por ejemplo, una /var/runentrada, 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á sleepejecutando 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 $pides 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 $pidte dice si $pidexiste 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 0señ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 -0y kill -s 0estilos de línea de comandos (kill (1p)).
A diferencia de la interfaz kill syscall, el killcomando 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 errnovalor (por ejemplo, un ejemplo de Python ).
trapcomando de Bash y 0 frente a una señal 0 dekill: ¿Qué es la señal 0 en un comando de captura?