如何使用Ruby和IO.popen编写和读取进程?

时间:2010-09-06 15:45:59

标签: ruby popen

我写了这个,但它没有用......

output = IO.popen("irb", "r+") do |pipe|
  pipe.gets
  pipe.puts "10**6"
  pipe.gets
  pipe.puts "quit"
end

我重写了

IO.popen("irb", "w+") do |pipe|
  3.times {puts pipe.gets} # startup noise
  pipe.puts "10**6\n"
  puts pipe.gets # I expect " => 1000000"
  pipe.puts "quit" # I expect exit from irb
end 
但它也不起作用

2 个答案:

答案 0 :(得分:3)

要么

IO.popen("ruby", "r+") do |pipe|
  pipe.puts "puts 10**6"
  pipe.puts "__END__"
  pipe.gets
end

或做

IO.popen("irb", "r+") do |pipe|
  pipe.puts "\n"
  3.times {pipe.gets} # startup noise
  pipe.puts "puts 10**6\n"
  pipe.gets # prompt
  pipe.gets
end

答案 1 :(得分:2)

一般情况下,上面的例子会挂起,因为管道仍然可以写入,而你调用的命令(ruby解释器)需要更多的命令/数据。

另一个答案会将__END__发送给ruby - 这可以在这里运行,但这个技巧当然不适用于您可能通过popen调用的任何其他程序。

当您使用popen时,需要使用IO#close_write关闭管道。

 IO.popen("ruby", "r+") do |pipe|
   pipe.puts "puts 10**6"

   pipe.close_write    # make sure to close stdin for the program you call

   pipe.gets
 end

另见:

Ruby 1.8.7 IO#close_write

Ruby 1.9.2 IO#close_write