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 killy 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
killtiene un nombre erróneo porque no necesariamente mata el proceso. Simplemente envía una señal al proceso.kill $PIDes 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 indicakillque 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 una0devolució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
-pes innecesario, al menos en ese caso.ps $PIDtiene 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-ndé un resultado válido.fuente
if ps -p"$PID" -o "pid=" >/dev/null 2>&1; then echo "Process is running..."; fipsopciones y características tienden a variar entre plataformas, por lo que aún no es completamente portátil.$PIDestá vacío[ -e /proc/$PID ], aún devolverá verdadero, ya que el/proc/directorio todavía existe.pscomando con-p $PIDpuede 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/$PIDdirectorio. 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/exeNo es un archivo normal. Por lo tanto,[ -f /proc/$PID/exe ]siempre devolverá unfalseresultado. Tratar[ -h /proc/$PID/exe ].Parece que quieres
que volverá cuando
$pidtermine.De lo contrario, puede usar
para verificar si el proceso aún está vivo (esto es más efectivo que
kill -0 $pidporque funcionará incluso si no posee el pid).fuente
pid 123 is not a child of this shellCreo 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, usekillel 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
pidofno 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,pidofestablece 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 valorPidmás adelante) simplementeif pidof 'process_name'; then...pidofejemplo está lleno de malentendidos sobre cómotestfunciona 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