Rubyスクリプトから別のRubyスクリプトを呼び出したい時がある.
そういう場合,
msg=`hoge.rb`
とすると,hoge.rbが標準出力へ出力した文字列すべてを変数msgで受け取ることが出来る.
1行ずつ受け取って処理したい場合は,
IO.popen("hoge.rb") do |pipe| pipe.each do | line | print line end end
という感じにすれば,1行ずつとって表示することが出来る.
しかし,デフォルトだと,Rubyスクリプトの標準出力はバッファリングされるため,hoge.rbの処理に時間がかかる場合,長い時間立った後に,まとめてhoge.rbの出力をどかっと渡されるようになる.
(受け取ったプログラムは,それを1行ずつ処理することはできるけれど)
これは標準出力がバッファリングされているのが原因なので,バッファリングしないようにすればOK.
つまり,呼び出される側のスクリプトhoge.rbの最初に,
STDOUT.sync = true
と書けば良い.
([Ruby] Rubyの標準出力をバッファしないを参考にしました.)
これで,ばっちり動く.
例(STDOUT.sync=trueの有無での挙動の違いを確認)
呼び出される側:hoge.rb
#!/usr/bin/ruby STDOUT.sync = true puts "hoge" sleep 3 # 長時間かかる処理 puts "hoge"
呼び出す側:main.rb
#!/usr/bin/ruby puts "start" IO.popen("test.rb") do |f| f.each do |line| print line end end puts "finish"