Respuestas:
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 a kill -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 indica kill
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/signal
kill -0
, de hecho, tengo que hacer esto: kill -0 25667 ; echo $?
- y luego, si recibo una 0
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:
if ps -p $PID > /dev/null
then
echo "$PID is running"
# Do something knowing the pid exists, i.e. the process with $PID is running
fi
El problema con:
kill -0 $PID
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:
kill -0 1
y
kill -0 $non-running-pid
tener un código de salida indistinguible (no cero) para un usuario normal, pero el proceso de inicio (PID 1) ciertamente se está ejecutando.
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?
-p
es innecesario, al menos en ese caso. ps $PID
tiene exactamente el mismo resultado.
if [ -n "$PID" -a -e /proc/$PID ]; then
echo "process exists"
fi
o
if [ -n "$(ps -p $PID -o pid=)" ]
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.
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.
Tienes dos formas:
Comencemos buscando una aplicación específica en mi computadora portátil:
[root@pinky:~]# ps fax | grep mozilla
3358 ? S 0:00 \_ /bin/sh /usr/lib/firefox-3.5/run-mozilla.sh /usr/lib/firefox-3.5/firefox
16198 pts/2 S+ 0:00 \_ grep mozilla
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:
[root@pinky:~]# ps aux | awk '{print $2 }' | grep 3358
3358
Entonces su código será:
if [ ps aux | awk '{print $2 }' | grep -q $PID 2> /dev/null ]; then
kill $PID
fi
Segunda forma : solo busca algo en el /proc/$PID
directorio. Estoy usando "exe" en este ejemplo, pero puedes usar cualquier otra cosa.
[root@pinky:~]# ls -l /proc/3358/exe
lrwxrwxrwx. 1 elcuco elcuco 0 2010-06-15 12:33 /proc/3358/exe -> /bin/bash
Entonces su código será:
if [ -f /proc/$PID/exe ]; then
kill $PID
fi
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.
/proc/$PID/exe
No es un archivo normal. Por lo tanto, [ -f /proc/$PID/exe ]
siempre devolverá un false
resultado. Tratar [ -h /proc/$PID/exe ]
.
Parece que quieres
wait $PID
que volverá cuando $pid
termine.
De lo contrario, puede usar
ps -p $PID
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).
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?
kill -9
. Eso mata instantáneamente el proceso y no le da la oportunidad de limpiar después de sí mismo. En su lugar, use kill
el equivalente a kill -15
. Si eso no funciona, debe averiguar por qué, y solo como último recurso kill -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.
#!/bin/bash
if [ -f .pid ]; then
read pid < .pid
echo $pid
ps -p $pid > /dev/null
r=$?
if [ $r -eq 0 ]; then
echo "$pid is currently running, not executing $0 twice, exiting now..."
exit 1
fi
fi
echo $$ > .pid
# do things here
rm .pid
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".
Por ejemplo, en GNU / Linux puedes usar:
Pid=$(pidof `process_name`)
if [ $Pid > 0 ]; then
do something
else
do something
fi
O algo como
Pin=$(ps -A | grep name | awk 'print $4}')
echo $PIN
y eso te muestra el nombre de la aplicación, solo el nombre sin ID.
pidof
no devuelve un número negativo, ya que un PID negativo no tiene ningún sentido, y no puede matar init
, 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 es if Pid=$(pidof 'process_name'); then ...
o (si no necesita el valor Pid
más adelante) simplementeif pidof 'process_name'; then...
pidof
ejemplo está lleno de malentendidos sobre cómo test
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.
#!/bin/bash
PID=$(ps aux | grep '/usr/bin/python2.7 manage.py SES__boto3_sqs_read' | grep -v grep | awk '{print $2}')
if [[ -z $PID ]]; then
/usr/bin/python2.7 /home/brian/djcode/proyectoONE/manage.py SES__boto3_sqs_read
else
echo "do nothing, just smile =)"
fi
exit $?