こう言う風に、少しずつ結果が標準出力に流れてくるコマンドがあるとします。
test.rb
5.times.each do |i|
sleep 0.2
puts i
end
% ruby test.rb # 0.2秒間隔で現れる
0
1
2
3
4
これをRubyから外部コマンドとして普通に実行すると、コマンドが全て完了してからいっきに結果が得られます。
% ruby -e 'puts `ruby test.rb`' # 1秒後に一気に現れる
0
1
2
3
4
Rubyからそのコマンドの結果を受け取りたい場合はこれでもよいですが、例えばスクリプトからRakeタスクを実行するような場合は、標準出力に遅延なく流して欲しいです。Open3.pipeline
使うとそれができます。
% ruby -r open3 -e 'Open3.pipeline("ruby test.rb")' # 0.2秒間隔で現れる
0
1
2
3
4
サブプロセスを立ち上げてその標準出力を自分の標準出力につなげているだけなので、色などもそのまま表示されます。
% cat test.zsh
autoload -U colors; colors
echo ${fg[green]}green
sleep 0.2
echo ${fg[blue]}blue
% ruby -r open3 -e 'Open3.pipeline("zsh test.zsh")' # 緑でgreen, 青でblueと表示される
green
blue