別のツールからいくつかのテストを実行するための Thor スクリプトを作成しています。つまり、シェル コマンドを実行しています。コマンドからの stdout と stderr を継続的にコンソールに出力したいと思います。
最初の試みは単にバッククォートを使用することでしたが、当然、stdout/stderr は出力されません (むしろ、stdout は戻り値に取り込まれます)。
desc "mytask", "my description"
def mytask
`run-my-tests.sh`
end
私の次のアプローチは、次のように Open3 を使用することでした。
require "open3"
desc "mytask", "my description"
def mytask
Open3.popen3("run-my-tests.sh") do |stdin, stdout, stderr|
STDOUT.puts(stdout.read())
STDERR.puts(stderr.read())
end
end
ただし、上記のアプローチでは、stdout と stderr の両方から出力全体が取得され、最後にのみ出力されます。私のユースケースでは、失敗したテストと合格したテストの出力が利用可能になったときに表示したいと思います。
http://blog.bigbinary.com/2012/10/18/backtick-system-exec-in-ruby.htmlから、ストリームをチャンク単位で、つまり のgets()
代わりに を使用して読み取ることができることがわかりましたread()
。例えば:
require "open3"
desc "mytask", "my description"
def mytask
Open3.popen3(command) do |stdin, stdout, stderr|
while (out = stdout.gets()) || err = (stderr.gets())
STDOUT.print(out) if out
STDERR.print(err) if err
end
exit_code = wait_thr.value
unless exit_code.success?
raise "Failure"
end
end
end
それは最善かつ最もクリーンなアプローチのように見えますか? stderrの前に手動で stdout を印刷しようとする必要があるのは問題ですか?