Estoy escribiendo un script de Perl que analiza los archivos de registro para recopilar PID y luego comprueba si ese PID se está ejecutando. Estoy tratando de pensar en la mejor manera de hacer esa verificación. Obviamente, podría hacer algo como:
system("ps $pid > /dev/null") && print "Not running\n";
Sin embargo, preferiría evitar la llamada al sistema si es posible. Por lo tanto, pensé que podría usar el /proc
sistema de archivos (la portabilidad no es una preocupación, esto siempre se ejecutará en un sistema Linux). Por ejemplo:
if(! -d "/proc/$pid"){
print "Not running\n";
}
¿Eso es seguro? ¿Puedo suponer siempre que si no hay un /proc/$pid/
directorio, el PID asociado no se está ejecutando? Lo espero ya que AFAIK ps
obtiene su información de /proc
todos modos, pero como esto es para el código de producción, quiero estar seguro.
Entonces, ¿puede haber casos en que un proceso en ejecución no tenga un /proc/PID
directorio o donde /proc/PID
exista un directorio y el proceso no se esté ejecutando? ¿Hay alguna razón para preferir el análisis antes que ps
verificar la existencia del directorio?
fuente
kill
función perl que usa la señal 0, que no mata pero dice si puede hacerlo (es decir, necesita permiso para señalar ese proceso).kill -0
sea el mejor), esto solo le indica si hay un proceso en ejecución con el PID dado . No le dice si el proceso seguirá ejecutándose un milisegundo más tarde, y no le dice si el proceso es el que le interesa o si es un proceso no relacionado al que se le asignó el mismo PID después de que el proceso interesante falleció. . Casi siempre es un error probar si se está ejecutando un PID dado : hay muy pocas circunstancias en las que esto no sea propenso a las condiciones de carrera.Respuestas:
Se
kill(0,$pid)
puede usar la función perl .Si el código de retorno es 1, entonces existe el PID y se le permite enviarle una señal.
Si el código de retorno es 0, entonces debe verificar $ !. Puede ser EPERM (permiso denegado), lo que significa que el proceso existe o ESRCH, en cuyo caso el proceso no existe.
Si su código de comprobación se está ejecutando como
root
entonces, puede simplificar esto simplemente comprobando el código de retorno de kill; 0 => error, 1 => okPor ejemplo:
Esto se puede convertir en una función simple
fuente
if (!kill(0,$pid) && $! =~ /No such process/){ exit; }
o similar. SinErrno
embargo, me gusta más tu solución, gracias. Si bien probablemente seguiré con esto, esperaré un tiempo en caso de que alguien pueda responder la pregunta subyacente de Linux./proc
se monta entonces cada PID visible en el espacio de nombres estará presente, por lo que su-d /proc/$pid
prueba sería trabajar ... pero se trata de salir al sistema de archivos en lugar de utilizar las llamadas al sistema nativas.system
llamada", es decir, una llamada a lasystem
función en sí, no una "llamada al sistema" . Lo último no se puede evitar, pero lo primero sí se puede. Tiene sentido ahora!/proc/PID
kill 0
/proc
/proc
ps
top
lsof
), y creo que no hay ninguna garantía de que exista (es decir, POSIX no lo requiere). Y, a menos que el sistema esté completamente conectado,kill
funcionará./proc
requiere leer el directorio raíz para encontrar el/proc
sistema de archivos. Esto es cierto para cualquier intento de acceder a cualquier archivo por una ruta absoluta, incluyendo cosas en/bin
,/etc
y/dev
. Esto sucede con tanta frecuencia que el directorio raíz seguramente se almacena en memoria caché durante toda la vida útil (tiempo de actividad) del sistema, por lo que este paso se puede realizar sin ninguna E / S de disco. Y, una vez que tiene el inodo de/proc
, todo lo demás que sucede está en la memoria./proc
? Constat
,open
,readdir
, etc, que son el sistema nativo llama exactamente igual que comokill
.La pregunta habla sobre un proceso en ejecución. Esta es una frase resbaladiza. Si realmente desea probar si el proceso se está ejecutando (es decir, en la cola de ejecución; tal vez el proceso actual en alguna CPU; sin dormir, esperando o detenido), es posible que deba hacer una lectura del resultado , o mirar . Pero no veo indicios en su pregunta o comentario de que esté preocupado por esto.
ps PID
/proc/PID/stat
El elefante en la habitación, sin embargo, es que un proceso de zombie 2 puede ser difícil de distinguir de un proceso que está vivo y bien.
kill 0
funciona en un zombi, y existe. Puede identificar zombies con las técnicas enumeradas en el párrafo anterior (hacer y leer el resultado, o mirar ). Mi prueba muy rápida y ocasional (es decir, no muy a fondo) sugiere que también se puede hacer esto haciendo una o en , o - estos fallarán en zombis. (Sin embargo, también fallarán en procesos que no son de su propiedad)./proc/PID
ps PID
/proc/PID/stat
readlink
lstat
/proc/PID/cwd
/proc/PID/root
/proc/PID/exe
____________
1 si la opción
-f
( f orce) no funciona, intente-l
( l azy).2 es decir, un proceso que ha salido / muerto / terminado, pero cuyo padre aún no ha hecho a
wait
.fuente
kill(2)
manual indique directamente el comportamiento que usted señaló, pero la página delperlfunc
manual sí. Enviaré un correo electrónico a Michael Kerrisk para ver qué tiene que decir sobre la página de manual del sistema.kill(2)
sobre los permisos para "enviar" la señal 0.kill(2)
manual (todavía no lo veo en línea): "Si sig es 0, entonces no se envía ninguna señal, pero aún se realizan verificaciones de existencia y permiso; esto puede usarse para verificar la existencia de un ID de proceso o ID de grupo de proceso que la persona que llama tiene permitido señalar ".