0

別のツールからいくつかのテストを実行するための 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 を印刷しようとする必要があるのは問題ですか?

4

2 に答える 2