Process.spawn (Ruby 1.9.x): 如何检查产卵是否成功并检测错误?

Process.spawn (Ruby 1.9.x): How to check if spawning was successful and detect errors?

使用跨平台解决方案(GNU/Linux、Windows),我想在后台生成一个外部程序,捕获它 pid,然后通过以下方式停止程序存储的 pid.

考虑 Ruby 中的这段代码 1.9.x:

pid = Process.spawn("xxx")
puts pid

stdout/stderr:

8117
sh: 1: xxx: not found

没有抛出异常,而且我没有看到任何方法来检测生成不成功的事实(xxx 不是有效命令)。

检测此生成不成功的最佳方法是什么?

Process#spawn returns 进程 ID。如果你得到一个进程 ID,那么从技术上讲,函数本身并没有失败。在Ruby >= 2.0.0 中,Process#spawn 找不到命令会抛出Errno::ENOENT。由于 ruby 1.9 不受支持,最好的解决方案是升级 ruby.

一个可能有用的 hack 是测试调用 returns 之后进程是否真的 运行。遗憾的是,这将是特定于平台的。

pid = Process.spawn("xxx")
case RUBY_PLATFORM
when /linux/i
  success = File.exist?("/proc/#{pid}")
when /windows/i
  # use win32api gem, Windows API call EnumProcesses
else
  # ?  
end

不幸的是,如果在您测试其存在时该进程已完成,您将无法判断。您可能想检查它的结果(无论它做什么),看看它是否也这样做了。

如果您控制正在启动的程序,另一种方法是在启动之前打开一个命名管道,并让它通过管道向您的 ruby 程序发送一条消息,表明它是 运行。然后,您可以在 spawn 调用后以非阻塞方式从管道中读取,并使用 Timeout 来防止它永远阻塞。一种更简单、不太干净的方法是让该程序将一些确定性的东西写入一个文件,您可以使用一个简单的 File.exist? 测试来查看它是否存在。