用超时和捕捉输出叉subprocess

说我有一个像下面的函数,我如何捕获Process.spawn调用的输出? 如果超过指定的超时时间,我也应该能够终止进程

请注意,该function也必须是跨平台的(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 

谢谢。

您可以使用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 

原始资料来自features / support / filesystem.rb

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

希望这可以帮助。

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

我在这里的Ruby论坛上关注了Anselm的建议。

该函数看起来像这样 –

 def execute_with_timeout!(command) begin pipe = IO.popen(command, 'r') rescue Exception => e raise "Execution of command #{command} unsuccessful" end output = "" begin status = Timeout::timeout(timeout) { Process.waitpid2(pipe.pid) output = pipe.gets(nil) } rescue Timeout::Error Process.kill('KILL', pipe.pid) end pipe.close output end 

这样做的工作,但我宁愿使用包装这个功能的第三方gem。 任何人有更好的方法来做到这一点? 我已经尝试过终结者 ,它正是我想要的,但它似乎并没有在Windows上工作。