如何从Ruby检查具有特定pid的进程是否正在运行?

如果有多种方法,请列出它们。 我只知道一种,但是我想知道是否有一种更干净的Ruby方式。

Pistos asked 2020-06-29T22:05:11Z
9个解决方案
59 votes

Process.getpgidProcess::kill方法之间的差异似乎是当pid存在但由另一个用户拥有时发生的事情。 Process.getpgid将返回答案,Process::kill将引发异常(Errno::EPERM)

基于此,我建议您选择Process.getpgid,仅是因为它使您不必捕获两个不同的异常。

这是我使用的代码:

begin
  Process.getpgid( pid )
  true
rescue Errno::ESRCH
  false
end
tonystubblebine answered 2020-06-29T22:05:58Z
47 votes

如果这是您希望“拥有”的进程(例如,您正在使用它来验证您控制的进程的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
>> 
Dustin answered 2020-06-29T22:05:29Z
46 votes

@John T,@ Dustin:其实,伙计们,我细读了Process rdocs,它看起来像

Process.getpgid( pid )

是应用相同技术的一种较不暴力的手段。

Pistos answered 2020-06-29T22:06:22Z
27 votes

对于子进程,其他解决方案(例如发送信号)将无法达到预期效果:它们将指示该进程在实际退出时仍在运行。

如果要检查自己生成的进程,可以使用Process.waitpid。 如果您使用的是Errno::ECHILD: No child processes标志,并且子进程没有退出,则将返回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。

balu answered 2020-06-29T22:07:01Z
6 votes

这就是我一直在做的事情:

def alive?(pid)
  !!Process.kill(0, pid) rescue false
end
komatsu answered 2020-06-29T22:07:20Z
4 votes

您可以尝试使用

Process::kill 0, pid

其中pid是pid号,如果pid正在运行,则应返回1。

John T answered 2020-06-29T22:07:45Z
4 votes

在Linux下,您可以使用proc文件系统获得许多正在运行的程序的属性:

File.read("/proc/#{pid}/cmdline")
File.read("/proc/#{pid}/comm")
amenzhinsky answered 2020-06-29T22:08:05Z
0 votes

*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
Daniel Doezema answered 2020-06-29T22:08:33Z
0 votes

我已经解决了这个问题,昨天我将其编译为“ process_exists” gem。

它使用给定的pid将空信号(0)发送到进程以检查其是否存在。 即使当前用户没有权限将信号发送到接收进程,它也可以工作。

用法:

require 'process_exists'

pid = 12
pid_exists = Process.exists?(pid)
Wilson Silva answered 2020-06-29T22:09:02Z
translate from https://stackoverflow.com:/questions/325082/how-can-i-check-from-ruby-whether-a-process-with-a-certain-pid-is-running