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

Rob*_*nes 19 ruby linux command-line

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

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

一个例子:

for foo in bar
    IO.popen(cmd_foo)
end
IO.popen(another_cmd)
Run Code Online (Sandbox Code Playgroud)

所以cmd_foosanother_cmd运行之前都需要返回.

Rob*_*mme 19

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

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
Run Code Online (Sandbox Code Playgroud)

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


rog*_*ack 17

显然,执行此操作的规范方法是:

 Process.wait(popened_io.pid)
Run Code Online (Sandbox Code Playgroud)


Rob*_*nes 6

for foo in bar
  out = IO.popen(cmd_foo)
  out.readlines
end
IO.popen(another_cmd)
Run Code Online (Sandbox Code Playgroud)

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

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


And*_*w Y 5

我认为您需要将IO.popen循环内调用的结果分配给变量,并继续调用read()它们,直到eof()所有变量变为真为止。

然后,您知道所有程序都已完成执行,就可以开始了another_cmd

  • 需额外注意的是:使用IO方法的块形式通常更安全。另外,在1.9中,由于块变量具有不同的作用域,从而阻止了在块外修改相同命名变量,因此您会获得更高的鲁棒性(并且您会得到警告)。 (2认同)