fork子进程与超时和捕获输出

the*_*oid 9 ruby linux windows stdout process

假设我有类似下面的函数,如何捕获Process.spawn调用的输出?如果进程花费的时间超过指定的超时时间,我也应该能够终止进程.

请注意,该功能还必须是跨平台的(Windows/Linux).

def execute_with_timeout!(command)
  begin
    pid = Process.spawn(command)     # How do I capture output of this process?
    status = Timeout::timeout(5) {
      Process.wait(pid)
    }
  rescue Timeout::Error
    Process.kill('KILL', pid)
  end
end
Run Code Online (Sandbox Code Playgroud)

谢谢.

Lui*_*ena 12

您可以使用IO.pipe并告诉Process.spawn使用重定向输出而无需外部gem.

当然,只从Ruby 1.9.2开始(我个人推荐1.9.3)

以下是Spinach BDD内部用于捕获out和err输出的简单实现:

# stdout, stderr pipes
rout, wout = IO.pipe
rerr, werr = IO.pipe

pid = Process.spawn(command, :out => wout, :err => werr)
_, status = Process.wait2(pid)

# close write ends so we could read them
wout.close
werr.close

@stdout = rout.readlines.join("\n")
@stderr = rerr.readlines.join("\n")

# dispose the read ends of the pipes
rout.close
rerr.close

@last_exit_status = status.exitstatus
Run Code Online (Sandbox Code Playgroud)

原始源位于features/support/filesystem.rb中

强烈建议您阅读Ruby自己的Process.spawn文档.

希望这可以帮助.

PS:我把超时实现作为你的功课;-)

  • @TamerShlash读取`Process.wait2`文档,它返回一个元组(两个值),我们将一个分配给`status`而另一个(第一个)分配给_,这是你想要丢弃一个的常见做法值. (3认同)