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?

¿Fue útil?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top