En un script bash, quiero hacer lo siguiente (en pseudocódigo):
if [ a process exists with $PID ]; then
kill $PID
fi
¿Cuál es la expresión apropiada para la declaración condicional?
Para verificar la existencia de un proceso, use
kill -0 $pid
Pero justo como dijo @unwind, si vas a matarlo de todos modos, solo
kill $pid
o tendrás una condición de carrera.
Si desea ignorar la salida de texto kill
y hacer algo basado en el código de salida, puede
if ! kill $pid > /dev/null 2>&1; then
echo "Could not send SIGTERM to process $pid" >&2
fi
kill
tiene un nombre erróneo porque no necesariamente mata el proceso. Simplemente envía una señal al proceso.kill $PID
es equivalente akill -15 $PID
, que envía la señal 15, SIGTERM al proceso, que es una instrucción para finalizar. No hay una señal 0, ese es un valor especial que indicakill
que solo se verifique si se puede enviar una señal al proceso, que para la mayoría de los propósitos es más o menos equivalente a verificar si existe. Ver linux.die.net/man/2/kill y linux.die.net/man/7/signalkill -0
, de hecho, tengo que hacer esto:kill -0 25667 ; echo $?
- y luego, si recibo una0
devolución, entonces el proceso con ese PID puede cancelarse; y si el PID del proceso (por ejemplo) no existe, lo$?
será1
, lo que indica un error. ¿Es eso correcto?La mejor manera es:
El problema con:
es que el código de salida no será cero, incluso si el pid se está ejecutando y no tiene permiso para eliminarlo. Por ejemplo:
y
tener un código de salida indistinguible (no cero) para un usuario normal, pero el proceso de inicio (PID 1) ciertamente se está ejecutando.
DISCUSIÓN
Las respuestas sobre las condiciones de muerte y carrera son exactamente correctas si el cuerpo de la prueba es una "muerte". Vine buscando el general " ¿cómo se prueba una existencia de PID en bash "?
El método / proc es interesante, pero en cierto sentido rompe el espíritu de la abstracción del comando "ps", es decir, no necesita buscar en / proc porque ¿qué pasa si Linus decide llamar al archivo "exe" de otra manera?
fuente
-p
es innecesario, al menos en ese caso.ps $PID
tiene exactamente el mismo resultado.o
En la última forma,
-o pid=
es un formato de salida para mostrar solo la columna de ID de proceso sin encabezado. Las comillas son necesarias para que el operador de cadena no vacía-n
dé un resultado válido.fuente
if ps -p"$PID" -o "pid=" >/dev/null 2>&1; then echo "Process is running..."; fi
ps
opciones y características tienden a variar entre plataformas, por lo que aún no es completamente portátil.$PID
está vacío[ -e /proc/$PID ]
, aún devolverá verdadero, ya que el/proc/
directorio todavía existe.ps
comando con-p $PID
puede hacer esto:fuente
Tienes dos formas:
Comencemos buscando una aplicación específica en mi computadora portátil:
Todos los ejemplos buscarán ahora el PID 3358.
Primera forma : Ejecute "ps aux" y grep para el PID en la segunda columna. En este ejemplo busco firefox y luego su PID:
Entonces su código será:
Segunda forma : solo busca algo en el
/proc/$PID
directorio. Estoy usando "exe" en este ejemplo, pero puedes usar cualquier otra cosa.Entonces su código será:
Por cierto: ¿qué tiene de malo
kill -9 $PID || true
?EDITAR:
Después de pensarlo durante unos meses ... (alrededor de 24 ...) la idea original que di aquí es un buen truco, pero altamente inportable. Si bien enseña algunos detalles de implementación de Linux, no funcionará en Mac, Solaris o * BSD. Incluso puede fallar en futuros núcleos de Linux. Por favor, use "ps" como se describe en otras respuestas.
fuente
/proc/$PID/exe
No es un archivo normal. Por lo tanto,[ -f /proc/$PID/exe ]
siempre devolverá unfalse
resultado. Tratar[ -h /proc/$PID/exe ]
.Parece que quieres
que volverá cuando
$pid
termine.De lo contrario, puede usar
para verificar si el proceso aún está vivo (esto es más efectivo que
kill -0 $pid
porque funcionará incluso si no posee el pid).fuente
pid 123 is not a child of this shell
Creo que es una mala solución, que se abre a las condiciones de carrera. ¿Qué pasa si el proceso muere entre su prueba y su llamado a matar? Entonces matar fallará. Entonces, ¿por qué no simplemente intentar matar en todos los casos y verificar su valor de retorno para averiguar cómo fue?
fuente
kill -9
. Eso mata instantáneamente el proceso y no le da la oportunidad de limpiar después de sí mismo. En su lugar, usekill
el equivalente akill -15
. Si eso no funciona, debe averiguar por qué, y solo como último recursokill -9
.aquí almaceno el PID en un archivo llamado .pid (que es algo así como / run / ...) y solo ejecuto el script si aún no se está ejecutando.
nota: hay una condición de carrera ya que no comprueba cómo se llama ese pid. Si el sistema se reinicia y existe .pid pero es utilizado por una aplicación diferente, esto podría tener "consecuencias imprevistas".
fuente
Por ejemplo, en GNU / Linux puedes usar:
O algo como
y eso te muestra el nombre de la aplicación, solo el nombre sin ID.
fuente
pidof
no devuelve un número negativo, ya que un PID negativo no tiene ningún sentido, y no puede matarinit
, por lo que su condicional no tiene sentido (y además, necesitaría escapar>
para evitar que realice una redirección). Desea verificar si hay un resultado vacío, pero, por supuesto, como cualquier herramienta decente,pidof
establece un código de salida para decirle si funcionó, por lo que la solución adecuada esif Pid=$(pidof 'process_name'); then ...
o (si no necesita el valorPid
más adelante) simplementeif pidof 'process_name'; then...
pidof
ejemplo está lleno de malentendidos sobre cómotest
funciona bash . gnu.org/software/bash/manual/html_node/…el código a continuación verifica si mi proceso se está ejecutando, si es así, no haga nada.
verifiquemos los mensajes nuevos de Amazon SQS solo cada hora y solo si el proceso no se está ejecutando.
fuente