started - bash get last pid
Cómo verificar si existe una identificación de proceso(PID) (9)
En un script bash, 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 declaración condicional?
Creo que es una mala solución, que se abre para las condiciones de carrera. ¿Qué pasa si el proceso muere entre su prueba y su llamada a matar? Entonces matar fallará. Entonces, ¿por qué no probar el kill en todos los casos y verificar su valor de retorno para descubrir cómo fue?
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 el código de salida será distinto de cero, incluso si el pid se está ejecutando y no tiene permiso para matarlo. Por ejemplo:
kill -0 1
y
kill -0 $non-running-pid
tiene un código de salida indistinguible (distinto de cero) para un usuario normal, pero el proceso de inicio (PID 1) ciertamente se está ejecutando.
DISCUSIÓN
Las respuestas que analizan las condiciones de muerte y carrera son exactas si el cuerpo de la prueba es "matar". Vine buscando al 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" algo más?
Para verificar la existencia de un proceso, use
kill -0 $pid
Pero igual que @unwind dijo, 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 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
Parece que quieres
wait $PID
que volverá cuando finalice $pid
.
De lo contrario, puedes usar
ps -p $PID
para comprobar si el proceso aún está activo (esto es más efectivo que kill -0 $pid
porque funcionará incluso si no posee el pid).
Por ejemplo, en GNU / Linux puedes usar:
Pid=$(pidof `process_name`)
if [ $Pid > 0 ]; then
do something
else
do something
fi
O algo así 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 identificación.
Tienes dos formas:
Comencemos por buscar 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 ahora buscarán PID 3358.
Primera forma : Ejecute "ps aux" y grep para el PID en la segunda columna. En este ejemplo busco Firefox, y luego es PID:
[root@pinky:~]# ps aux | awk ''{print $2 }'' | grep 3358
3358
Entonces tu 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
. 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 tu código será:
if [ -f /proc/$PID/exe ]; then
kill $PID
fi
Por cierto: ¿qué pasa con kill -9 $PID || true
kill -9 $PID || true
?
EDITAR:
Después de pensarlo por unos meses ... (alrededor de 24 ...) la idea original que di aquí es un truco agradable, pero muy poco práctico. Si bien enseña algunos detalles de implementación de Linux, no funcionará en Mac, Solaris o * BSD. Incluso puede fallar en futuros kernels de Linux. Por favor, use "ps" como se describe en otras respuestas.
aquí guardo 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 verifica cómo se llama a ese pid. si el sistema se reinicia y existe .pid pero es utilizado por una aplicación diferente, esto podría generar "consecuencias imprevistas".
ps
comando ps
con -p $PID
puede hacer esto:
$ ps -p 3531
PID TTY TIME CMD
3531 ? 00:03:07 emacs
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 necessary para el operador de cadena no vacía -n
para dar un resultado válido.