Как писать и читать из процесса с Ruby и IO.popen? - PullRequest
3 голосов
/ 06 сентября 2010

Я написал это, но это не сработало ...

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 ]

4 голосов
/ 06 сентября 2010

Либо сделать

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
2 голосов
/ 15 мая 2013

В общем случае приведенный выше пример зависнет, поскольку канал все еще открыт для записи , а вызванная вами команда (интерпретатор 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

...