A Day in the Life

stdout, stderr の出力を文字列として記録する

stdout, stderr の出力を文字列として記録する

別にグローバル変数でなくても良いんだけど、STDOUT/STDERR インスタンスの匿名クラスで stringio にも記録させる。

require 'stringio'
$str_stdout_err = StringIO.new
[STDOUT, STDERR].each do |io|
  io.instance_eval { class << self ;self; end }.class_eval do
    def write(*args)
      super *args
      $str_stdout_err.write(*args) unless $str_stdout_err.closed?
    end
  end
end

at_exit {
  $str_stdout_err.rewind
  open('/tmp/output.txt', 'w') {|f| f.puts $str_stdout_err.read}
  $str_stdout_err.close
}

具体的にどんなときに役に立つのかというと、端末の出力を最後ごそっととってファイルに保存(tee 使わず純粋にRubyでやりたい)とか、どっかに送信するときとかそんなときに使える。本来は Logger なりなんなりを使うべきだけど、標準出力/エラー出力をぶんどったほうが楽でてっとり早いことも多いですよね!