Как я могу проверить в Ruby, запущен ли процесс с определенным pid? - PullRequest
44 голосов
/ 28 ноября 2008

Если есть несколько способов, перечислите их. Я знаю только одно, но мне интересно, есть ли более чистый, рубиновый способ.

Ответы [ 9 ]

58 голосов
/ 25 августа 2010

Разница между подходами Process.getpgid и Process::kill заключается в том, что происходит, когда pid существует, но принадлежит другому пользователю. Process.getpgid вернет ответ, Process::kill выдаст исключение (Errno::EPERM).

Исходя из этого, я рекомендую Process.getpgid, хотя бы потому, что это избавляет вас от необходимости ловить два разных исключения.

Вот код, который я использую:

begin
  Process.getpgid( pid )
  true
rescue Errno::ESRCH
  false
end
46 голосов
/ 28 ноября 2008

@ John T, @Dustin: На самом деле, ребята, я просматривал rdocs процесса, и похоже, что

Process.getpgid( pid )

является менее насильственным средством применения той же техники.

46 голосов
/ 28 ноября 2008

Если это процесс, который вы ожидаете "владеть" (например, вы используете его для проверки pid для процесса, которым вы управляете), вы можете просто отправить ему sig 0.

>> Process.kill 0, 370
=> 1
>> Process.kill 0, 2
Errno::ESRCH: No such process
    from (irb):5:in `kill'
    from (irb):5
>> 
26 голосов
/ 17 января 2013

Для дочерних процессов другие решения, такие как отправка сигнала, не будут работать должным образом: они будут указывать, что процесс все еще выполняется, когда он действительно завершился.

Вы можете использовать Process.waitpid , если хотите проверить процесс, который вы создали сами. Вызов не будет заблокирован, если вы используете флаг Process::WNOHANG и nil будет возвращено, пока дочерний процесс не завершится.

Пример:

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

Если pid не принадлежит дочернему процессу, будет сгенерировано исключение (Errno::ECHILD: No child processes).

То же самое относится к Process.waitpid2 .

6 голосов
/ 11 сентября 2015

Вот как я это делал:

def alive?(pid)
  !!Process.kill(0, pid) rescue false
end
4 голосов
/ 03 января 2014

В Linux вы можете получить множество атрибутов работающей программы, используя файловую систему proc:

File.read("/proc/#{pid}/cmdline")
File.read("/proc/#{pid}/comm")
4 голосов
/ 28 ноября 2008

Вы можете попробовать использовать

Process::kill 0, pid

где pid - это номер pid, если pid работает, он должен вернуть 1.

0 голосов
/ 05 августа 2014

Я имел дело с этой проблемой раньше, а вчера я скомпилировал ее в гем " process_exists ".

Он отправляет нулевой сигнал (0) процессу с данным pid, чтобы проверить, существует ли он. Он работает, даже если текущий пользователь не имеет прав на отправку сигнала процессу получения.

Использование:

require 'process_exists'

pid = 12
pid_exists = Process.exists?(pid)
0 голосов
/ 05 сентября 2013

A *nix -подход только будет заключаться в ps и проверке, существует ли разделитель \n (новая строка) в возвращаемой строке.

Пример вывода IRB

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

Упаковано как метод

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