¿Cómo comprobar si (PID) existe un identificador de proceso
Pregunta
En una escritura del golpe, yo quiero hacer lo siguiente (en pseudo-código):
if [ a process exists with $PID ]; then
kill $PID
fi
¿Cuál es la expresión apropiada para la sentencia condicional?
Solución
para comprobar la existencia de un proceso, el uso
kill -0 $pid
Pero tal como dijo @unwind, si vas a matar de todos modos, simplemente
kill $pid
o tendrá una condición de carrera.
Si desea ignorar la salida de texto de 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
Otros consejos
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:
kill -0 $PID
es el código de salida será distinto de cero, incluso si el PID está en ejecución y usted no tiene permiso para matarlo. Por ejemplo:
kill -0 1
y
kill -0 $non-running-pid
tiene un (distinto de cero) código indistinguibles de salida para un usuario normal, pero el proceso init (PID 1) es, sin duda en ejecución.
discusión
Las respuestas discutir las condiciones de matar y la raza son exactamente correcto si el cuerpo de la prueba es una "matanza". Me fue a buscar al general " ¿cómo se prueba la existencia de un PID en bash ".
El método / proc es interesante, pero en algunos descansos sentido el espíritu de la "ps" abstracción de comandos, es decir, ya no tienes que ir a buscar en / proc porque lo que si Linus decide llamar el archivo "exe" algo más?
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 sólo la columna de la ID de proceso sin cabecera. Las citas son necesario para que no esté vacía -n
operador de cadena para dar resultado válido.
comando ps
con -p $PID
puede hacer esto:
$ ps -p 3531
PID TTY TIME CMD
3531 ? 00:03:07 emacs
Hay dos formas:
Vamos a empezar por buscar una aplicación específica en mi 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 ahora buscarán PID 3358.
Primera forma : Ejecutar "ps aux" y grep para el PID en la segunda columna. En este ejemplo busco Firefox, y luego para él es PID:
[root@pinky:~]# ps aux | awk '{print $2 }' | grep 3358
3358
Así que su código será:
if [ ps aux | awk '{print $2 }' | grep -q $PID 2> /dev/null ]; then
kill $PID
fi
Segundo manera : sólo tiene que buscar algo en el directorio /proc/$PID
. Estoy utilizando "exe" en este ejemplo, pero se puede 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
Así que su código será:
if [ -f /proc/$PID/exe ]; then
kill $PID
fi
Por cierto:? Cuál es incorrecto con kill -9 $PID || true
EDIT:
Después de pensarlo durante unos meses .. (unos 24 ...) la idea original que di aquí es un truco agradable, pero altamente no portables. Mientras que enseña unos pocos detalles de implementación de Linux, no será capaz de trabajar en Mac, Solaris o * BSD. Incluso puede fallar en futuros kernels de Linux. Por favor - el uso "ps" como se describe en otras respuestas
.creo que es una mala solución, que se abre a las condiciones de carrera. ¿Qué pasa si las matrices de proceso entre la prueba y su llamada para matar? Luego matar fallará. Así que ¿por qué no tratar la matanza en todos los casos, y comprobar su valor de retorno para averiguar cómo ha ido?
Parece que usted quiere
wait $PID
que devolverá cuando $pid
acabados.
contrario, puede utilizar
ps -p $PID
para comprobar si el proceso está todavía vivo (esto es más eficaz que kill -0 $pid
porque va a trabajar incluso si usted no es dueño del PID).
siguiente código comprueba si mi proceso está en marcha, si es así no hacer nada.
Vamos a ver los nuevos mensajes de Amazon SQS cada hora solamente y sólo 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 $?
aquí almaceno el PID en un archivo llamado .pid (que es algo así como / run / ...) y sólo ejecutar la secuencia de comandos si no está ya en ejecución.
#!/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 pid. Si el sistema se reinicia y .pid existe pero es utilizado por una aplicación diferente que esto podría provocar 'consecuencias imprevistas'.
Por ejemplo, en GNU / Linux puede utilizar:
Pid=$(pidof `process_name`)
if [ $Pid > 0 ]; then
do something
else
do something
fi
O algo así
Pin=$(ps -A | grep name | awk 'print $4}')
echo $PIN
y que muestra el nombre de la aplicación, sólo el nombre sin identificación.