Ruby と IO.popen を使用してプロセスを読み書きする方法は?
概要
Ruby と IO.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
解決策
一般に、上記の例は、パイプがまだ書き込みのために開いており、呼び出したコマンド (Ruby インタプリタ) がさらなるコマンド/データを期待しているため、ハングします。
もう 1 つの答えは、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 3.1 Popen*
さらに詳細に:
Ruby では、IO.popen、IO.popen2、IO.popen2e、および IO.popen3 はサブプロセスを操作するために使用されるメソッドであり、入力、出力、エラー ストリームの処理方法が異なります。ここでは、違いとそれぞれをいつ使用するかについて説明します。
各バージョンをいつ使用するかは、特定の要件によって異なります。