我怎样才能从Ruby中检查某个进程是否正在运行?

如果有多种方式,请列出它们。 我只知道一个,但我想知道是否有一个更清洁,ruby的方式。

如果这是一个你期望“拥有”的进程(例如,你正在使用它来validation你控制的进程的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 >> 

Process.getpgidProcess::kill方法之间的区别似乎是在pid存在但是被另一个用户所拥有时发生的。 Process.getpgid将返回一个答案, Process::kill将抛出exception(Errno::EPERM)

基于这一点,我推荐Process.getpgid ,如果只是因为它可以避免捕获两个不同的exception。

这是我使用的代码:

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

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

 Process.getpgid( pid ) 

是一种应用相同技术的较不激烈的手段。

对于subprocess,其他解决scheme(如发送信号)的行为不会像预期的那样:它们将指示进程在实际退出时仍在运行。

如果你想检查你自己产生的进程,你可以使用Process.waitpid 。 如果使用Process::WNOHANG标志,调用将不会被阻塞,只要subprocess没有退出, nil将被返回。

例:

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

如果pid不属于subprocess,则会抛出exception( Errno::ECHILD: No child processes )。

Process.waitpid2也是如此 。

你可以尝试使用

 Process::kill 0, pid 

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

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

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

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

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

一个*nix -only方法是将shellparsing为ps并检查返回的string中是否存在\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 

我之前和之前处理过这个问题,我把它编译成了“ process_exists ”gem。

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

用法:

 require 'process_exists' pid = 12 pid_exists = Process.exists?(pid) 

当我检查一个歌曲是否在Ruby代码中播放的时候,这对我有效

 def process_running?(pid) return true if pid false end def play_song_for_real @process_id = fork { exec 'afplay', $song_path } end 

如果你检查process_running(@process_id)你将在运行过程中process_running(@process_id) true,否则为false