如何等待进程完成使用IO.popen?

时间:2009-08-01 19:58:16

标签: ruby linux command-line

我在Ruby中使用IO.popen在循环中运行一系列命令行命令。然后我需要在循环外运行另一个命令。在循环中的所有命令都已终止之前,循环外的命令无法运行。

如何使程序等待这种情况发生?目前最后一个命令运行得太快了。

一个例子:

for foo in bar
    IO.popen(cmd_foo)
end
IO.popen(another_cmd)

因此,在cmd_foos运行之前,所有another_cmd都需要返回。

5 个答案:

答案 0 :(得分:18)

使用阻止表格并阅读所有内容:

IO.popen "cmd" do |io|
  # 1 array
  io.readlines

  # alternative, 1 big String
  io.read

  # or, if you have to do something with the output
  io.each do |line|
    puts line
  end

  # if you just want to ignore the output, I'd do
  io.each {||}
end

如果您没有读取输出,可能是进程阻塞了,因为连接其他进程和进程的管道已满,没有人从中读取。

答案 1 :(得分:6)

for foo in bar
  out = IO.popen(cmd_foo)
  out.readlines
end
IO.popen(another_cmd)

将输出读取到变量然后调用out.readlines就可以了。我认为out.readlines必须等待进程在返回之前结束。

感谢Andrew Y指出我正确的方向。

答案 2 :(得分:4)

我认为您需要将周期内IO.popen次调用的结果分配给变量,并继续调用read(),直到eof()成为真。< / p>

然后您知道所有程序都已完成执行,您可以启动another_cmd

答案 3 :(得分:3)

我建议您使用Thread.join同步最后popen次呼叫:

t = Thread.new do
    for foo in bar
       IO.popen(cmd_foo)
    end
end

t.join

IO.popen(another_cmd)

答案 4 :(得分:1)

您需要popen的输出吗?如果没有,您要使用Kernel#system还是其他命令?