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

发布于 2024-11-06 16:30:18 字数 530 浏览 0 评论 0原文

当我执行 $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

你能在不需要第二个过程的情况下做到这一点吗?

When I do $stdout.puts "foo", I want it to go to both stdout and to a file.

I came up with:

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

Can you do this without requiring a second process?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一抹淡然 2024-11-13 16:30:18

只需从 shell 中执行即可:

   your-program | tee file

Just do it from the shell:

   your-program | tee file
紫轩蝶泪 2024-11-13 16:30:18

我认为 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"

I think this post/thread from the Ruby mailing list may help you along: http://www.ruby-forum.com/topic/102759#226506

In particular this piece of code:

["$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"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文