将标准流程中的标准复制到标准输出和文件的最佳方法是什么?

时间:2011-05-12 21:15:02

标签: ruby unix

当我$stdout.puts "foo"时,我希望它转到stdout和文件。

我想出了:

def log_init
  $stdout.sync = true
  old_out = $stdout.dup
  old_out.sync = true
  r, w = IO.pipe
  $stdout.reopen(w)
  fork do
    f = File.open('/tmp/test', 'a') do |f|
      f.sync = true
      while (sel = IO.select([r], [], [], 1000))
        readfds, *rest = sel
        data = readfds.first.readpartial(1024)
        old_out.write(data)
        f.write(data)
      end
    end
  end
end

你可以不需要第二个过程吗?

2 个答案:

答案 0 :(得分:2)

只需从shell中执行:

   your-program | tee file

答案 1 :(得分:0)

我认为来自Ruby邮件列表的帖子/帖子可以帮助你:http://www.ruby-forum.com/topic/102759#226506

特别是这段代码:

["$stdout", "$stderr"].each do |std|
  io           = eval(std)
  old_write    = io.method(:write)

  class << io
    self
  end.module_eval do
    define_method(:write) do |text|
      unless text =~ /^[\r\n]+$/       # Because puts calls twice.
        File.open("logfile.log", "a") do |f|
          f.puts [std[1..-1].upcase, caller[2], text].join(" ")
        end
      end

      old_write.call(text)
    end
  end
end

$stdout.puts "text on stdout"
$stderr.puts "text on stderr"