将每个 bash 输出通过管道传输到文件
Pipe every bash output to file
有没有办法将每个输出通过管道传输到一个文件,比如监控终端以记录所有打印的内容?
此外,当我使用 tee
时,它似乎停止了实际程序的输出。我怎样才能改变这个?我想保持正常输出,只是用它的副本保存在文件中。
举个例子,我有这个 ruby 脚本:
100.times do |i|
puts i
end
并且运行 $ruby script.rb | tee output.txt
会很好地保存输出,但它只会在整个过程运行后打印出来。
用 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
,你每次都可以刷新文件并看到它每秒递增一个,即使脚本是 在媒体资源中;也就是说,还是运行ning。这是因为每次输出都是"flushing"
缺点: 您只能使用 bash 中的 script
命令执行此操作。在这方面,您创建了依赖关系;如果 script
不存在,或者它不像我机器上的 script
那样工作,那么这种方法可能根本不起作用。始终警惕依赖性。
自己做 Ruby
有时,您可能不会 运行 在 bash 上安装您的脚本,并且 script
可能不可用。然后怎样呢?好吧,您可以只创建一个打印到文件然后打印到标准输出的方法,而不管操作系统是什么。然后它会每次刷新文件以确保它是最新的。
# 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
缺点: 这将在您每次 运行 时清除文件。如果你想保留一个保存了很多 运行s 的长期日志,你可能需要修改这个小脚本。此外,如果您没有文件权限,此脚本将彻底崩溃。这 不是 用于生产,而只是作为对那些有兴趣实施这样的系统的人的概念验证。
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
缺点: 这是一个超越 hacky 的步骤,我 f运行kly 不建议实际这样做,除非你真的,真的知道你在做什么并且绝对必须。
有没有办法将每个输出通过管道传输到一个文件,比如监控终端以记录所有打印的内容?
此外,当我使用 tee
时,它似乎停止了实际程序的输出。我怎样才能改变这个?我想保持正常输出,只是用它的副本保存在文件中。
举个例子,我有这个 ruby 脚本:
100.times do |i|
puts i
end
并且运行 $ruby script.rb | tee output.txt
会很好地保存输出,但它只会在整个过程运行后打印出来。
用 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
,你每次都可以刷新文件并看到它每秒递增一个,即使脚本是 在媒体资源中;也就是说,还是运行ning。这是因为每次输出都是"flushing"
缺点: 您只能使用 bash 中的 script
命令执行此操作。在这方面,您创建了依赖关系;如果 script
不存在,或者它不像我机器上的 script
那样工作,那么这种方法可能根本不起作用。始终警惕依赖性。
自己做 Ruby
有时,您可能不会 运行 在 bash 上安装您的脚本,并且 script
可能不可用。然后怎样呢?好吧,您可以只创建一个打印到文件然后打印到标准输出的方法,而不管操作系统是什么。然后它会每次刷新文件以确保它是最新的。
# 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
缺点: 这将在您每次 运行 时清除文件。如果你想保留一个保存了很多 运行s 的长期日志,你可能需要修改这个小脚本。此外,如果您没有文件权限,此脚本将彻底崩溃。这 不是 用于生产,而只是作为对那些有兴趣实施这样的系统的人的概念验证。
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
缺点: 这是一个超越 hacky 的步骤,我 f运行kly 不建议实际这样做,除非你真的,真的知道你在做什么并且绝对必须。