¿Cómo puedo verificar desde Ruby si se está ejecutando un proceso con un determinado pid?

StackOverflow https://stackoverflow.com/questions/325082

  •  11-07-2019
  •  | 
  •  

Pregunta

Si hay más de una forma, enumerelas. Solo conozco uno, pero me pregunto si hay una forma más limpia y en rubí.

¿Fue útil?

Solución

Si es un proceso que espera '' poseer '' (por ejemplo, está usando esto para validar un pid para un proceso que controla), simplemente puede enviarle el signo 0.

>> Process.kill 0, 370
=> 1
>> Process.kill 0, 2
Errno::ESRCH: No such process
    from (irb):5:in `kill'
    from (irb):5
>> 

Otros consejos

La diferencia entre los enfoques Process.getpgid y Process :: kill parece ser lo que sucede cuando el pid existe pero es propiedad de otro usuario. Process.getpgid devolverá una respuesta, Process :: kill lanzará una excepción (Errno :: EPERM) .

Basado en eso, recomiendo Process.getpgid , aunque solo sea por la razón de que evita tener que atrapar dos excepciones diferentes.

Aquí está el código que uso:

begin
  Process.getpgid( pid )
  true
rescue Errno::ESRCH
  false
end

@John T, @Dustin: En realidad, muchachos, examiné el proceso rdocs, y parece que

Process.getpgid( pid )

es un medio menos violento de aplicar la misma técnica.

Para procesos secundarios, otras soluciones como enviar una señal no se comportarán como se espera: indicarán que el proceso aún se está ejecutando cuando salió realmente.

Puede usar Process.waitpid si desea verificar un proceso que generó usted mismo. La llamada no se bloqueará si está utilizando el indicador Process :: WNOHANG y nil se devolverá siempre que el proceso secundario no salga.

Ejemplo:

pid = Process.spawn('sleep 5')
Process.waitpid(pid, Process::WNOHANG) # => nil
sleep 5
Process.waitpid(pid, Process::WNOHANG) # => pid

Si el pid no pertenece a un proceso hijo, se lanzará una excepción ( Errno :: ECHILD: No hay procesos hijos ).

Lo mismo se aplica a Process.waitpid2 .

Así es como lo he estado haciendo:

def alive?(pid)
  !!Process.kill(0, pid) rescue false
end

Puedes intentar usar

Process::kill 0, pid

donde pid es el número pid, si el pid se está ejecutando, debería devolver 1.

En Linux puede obtener muchos atributos de ejecución de programas utilizando el sistema de archivos proc:

File.read("/proc/#{pid}/cmdline")
File.read("/proc/#{pid}/comm")

Un enfoque de * nix solo sería desplazar a ps y verificar si existe un delimitador \ n (nueva línea) en la cadena devuelta.

Ejemplo de salida IRB

1.9.3p448 :067 > `ps -p 56718`                                                          
"  PID TTY           TIME CMD\n56718 ttys007    0:03.38 zeus slave: default_bundle   \n"

Empaquetado como método

def process?(pid)  
  !!`ps -p #{pid.to_i}`["\n"]
end

He tratado este problema antes y ayer lo compilé en el " process_exists " joya.

Envía la señal nula (0) al proceso con el pid dado para verificar si existe. Funciona incluso si el usuario actual no tiene permisos para enviar la señal al proceso de recepción.

Uso:

require 'process_exists'

pid = 12
pid_exists = Process.exists?(pid)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top