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 /procsistema 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 psobtiene su información de /proctodos 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/PIDdirectorio o donde /proc/PIDexista un directorio y el proceso no se esté ejecutando? ¿Hay alguna razón para preferir el análisis antes que psverificar la existencia del directorio?
fuente

killfunció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 -0sea 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
rootentonces, 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. SinErrnoembargo, 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./procse monta entonces cada PID visible en el espacio de nombres estará presente, por lo que su-d /proc/$pidprueba sería trabajar ... pero se trata de salir al sistema de archivos en lugar de utilizar las llamadas al sistema nativas.systemllamada", es decir, una llamada a lasystemfunción en sí, no una "llamada al sistema" . Lo último no se puede evitar, pero lo primero sí se puede. Tiene sentido ahora!/proc/PIDkill 0/proc/procpstoplsof), 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,killfuncionará./procrequiere leer el directorio raíz para encontrar el/procsistema de archivos. Esto es cierto para cualquier intento de acceder a cualquier archivo por una ruta absoluta, incluyendo cosas en/bin,/etcy/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/statEl 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 0funciona 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/PIDps PID/proc/PID/statreadlinklstat/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 delperlfuncmanual 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 ".