将spawn()的stdout / stderr重定向到Ruby中的字符串

时间:2012-05-02 12:50:14

标签: ruby

我想使用spawn(用于多个并发子进程)在Ruby中执行外部进程,并将stdout或stderr收集到一个字符串中,其方式与Python的子进程Popen相似。通信()。

我尝试重定向:out /:err到一个新的StringIO对象,但是会产生一个ArgumentError,暂时重新定义$ stdxxx会混淆子进程的输出。

4 个答案:

答案 0 :(得分:6)

如果你不喜欢popen,这就是我的方式:

r, w = IO.pipe
pid = Process.spawn(command, :out => w, :err => [:child, :out]) 
w.close

...

pid, status = Process.wait2
output = r.read
r.close

无论如何,您无法直接重定向到String对象。您最多可以将它定向到IO对象,然后从中读取,就像上面的代码一样。

答案 1 :(得分:2)

为什么需要spawn?除非您使用的是Windows,否则可以使用popen*,例如popen4

require "open4"

pid, p_i, p_o, p_e = Open4.popen4("ls")
p_i.close
o, e = [p_o, p_e].map { |p| begin p.read ensure p.close end }
s = Process::waitpid2(pid).last

答案 2 :(得分:1)

最简单直接的方式似乎

require 'open3'

out, err, ps = Open3.capture3("ls")

puts "Process failed with status #{ps.exitstatus}" unless ps.success?

这里我们将输出作为字符串。

答案 3 :(得分:0)

从Ruby文档看来,你似乎不能,但你可以这样做:

spawn("ls", 0 => ["/tmp/ruby_stdout_temp", "w"])
stdoutStr=File.read("/tmp/ruby_stdout_temp")

您也可以对标准错误执行相同操作。或者,如果你不想这样做而不介意popen

io=IO.popen("ls")
stdout=io.read