将每个bash输出传递给文件

时间:2015-01-09 01:57:12

标签: ruby bash

有没有办法将每个输出传输到文件,例如监控终端以创建所有打印的历史记录?

另外,当我使用tee时,似乎停止了实际程序的输出。我怎么能改变这个?我想保持正常输出,只需使用它的副本保存在文件中。

就像一个例子,我有这个ruby脚本:

100.times do |i|
  puts i
end

运行$ruby script.rb | tee output.txt会很好地保存输出,但只会在整个运行后打印出来。

1 个答案:

答案 0 :(得分:3)

使用Bash进行操作

如果你正在使用bash(根据你的标签),你可以运行script -a -c "ruby your_script.rb" -f your_file.out

因此,例如,如果您编写了以下脚本,则将其另存为test.rb

# test.rb
i = 0
while true do
    i += 1
    puts i
    sleep 1
end

然后运行script -a -c "ruby test.rb" -f test.out,您每次都可以刷新文件并看到它每秒递增一次,即使脚本是在媒体资源中 ;也就是说,还在运行。这是因为它正在“刷新”每个输出。

DRAWBACKS:您只能在bash中使用script命令执行此操作。在这方面,你创建一个依赖;如果script不存在,或者它不能像我的机器上的script那样工作,那么这种方法可能根本不起作用。始终警惕依赖。

在Ruby中自己做

有时,您可能无法在bash上运行脚本,script可能无法使用。然后怎样呢?好吧,你可以创建一个打印到文件然后打印到stdout的方法,而不管操作系统如何。然后它会每次刷新文件以确保它是最新的。

# print_to_file.rb
class PrintOutputToFile
  def self.file
    @@file ||= File.open("my_output.log", "w")
  end

  def self.puts! some_data
    file.write "#{some_data}\n"
    file.flush
    puts some_data
  end
end

i = 0
while true do
  i += 1
  PrintOutputToFile.puts! i
  sleep 1
end

DRAWBACKS:每次运行时都会清除文件。如果要保留可以保存多次运行的长期日志,则可能需要修改此小脚本。此外,如果您没有文件权限,此脚本将彻底崩溃。 意味着用于制作,但仅作为对实施此类系统感兴趣的人的概念验证。

在Ruby中自己做的另一种方法

您也可以通过将旧的puts方法复制到proc中,然后覆盖核心puts方法来写入日志文件,但是通过调用原始puts方法来结束它。

@@old_puts = method(:puts).to_proc
def puts(output)
  @@file ||= File.open("your_log.txt", "w")
  @@file.write "#{output}\n"
  @@old_puts.call output
  @@file.flush
end

抽签:这是一个超越黑客的步骤,我坦率地不建议实际这样做,除非你真的,真的知道你在做什么,绝对必须。