如何使用Ruby检查正在运行的进程?

14

我使用调度器(Rufus scheduler)每分钟启动一个名为“ar_sendmail”(来自ARmailer)的进程。

为了不消耗内存,当已经有这样的进程正在运行时,该进程不应被启动。

如何检查是否已经运行此进程?在下面的 unless 后面加什么?

scheduler = Rufus::Scheduler.start_new

  scheduler.every '1m' do

    unless #[what goes here?]
      fork { exec "ar_sendmail -o" }
      Process.wait
    end

  end

end
3个回答

24
unless `ps aux | grep ar_sendmai[l]` != ""

谢谢!回答一个问题:为什么在“ar_sendmail”的“l”周围有括号? - TomDogg
9
这是为了从匹配ar_sendmail的进程中删除grep的调用过程,否则您将得到“grep ar_sendmail”的结果。 - stef
4
如果您想提取进程ID:ps aux | grep ar_sendmai[l] | awk '{ print $2 }' - phatmann
嗨!@stef,如果我使用一些Rails方法(例如Email.send_notifications)而不是上面的过程 - fork { exec "ar_sendmail -o" },该怎么做? - Anikethana
2
不要在 != 中使用 unless,因为它会导致精神痛苦。相反,请使用 if==if something == something_elseunless something != something_else 更容易理解。 - the Tin Man
对于更简单的检查,请使用 pidof ar_sendmail - Mike Lowery

8
unless `pgrep -f ar_sendmail`.split("\n") != [Process.pid.to_s]

1
我认为这是一个更好的解决方案,因为您不必使用括号来排除调用进程。 - while
编辑:由于pgrep的返回结构,需要在\n上进行拆分。 - dahlberg

1

我认为这样看起来更整洁,并且使用了内置的Ruby模块。发送一个0终止信号(即不要杀死):

  # Check if a process is running
  def running?(pid)
    Process.kill(0, pid)
    true
  rescue Errno::ESRCH
    false
  rescue Errno::EPERM
    true
  end

稍作修改,源自快速开发技巧。你可能不想要救援EPERM,意味着“它正在运行,但你无权终止它”。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接