如何将STDOUT和STDERR记录到单个文件中并使用Ruby在控制台中仅显示STDERR?
问题描述:
我可以做这样的事情在bash:如何将STDOUT和STDERR记录到单个文件中并使用Ruby在控制台中仅显示STDERR?
myCommand arg1 arg2 2>&1 >> myLogFolder/myLogFile.log | tee -a myLogFolder/myLogFile.log
我希望能够代替这样说:
log.rb myLogFolder/myLogFile.log myCommand arg1 arg2
使用log.rb脚本将完成两两件事:
- 结果在一个简单的语句与更少的重定向技巧和只有一个单一的日志文件的规范。
- 如有必要,创建日志文件夹。
我在看Ruby的popen和spawn选项,但我没有看到将STDERR流拆分为两个目标的方法。
答
此Ruby脚本满足我的需求,但也许有一个更好的办法
logPath = ARGV[0]
logFolder = File.dirname(logPath)
command = ARGV.slice(1..-1).join(" ")
`mkdir -p #{logFolder}`
exec "#{command} 2>&1 >> #{logPath} | tee -a #{logPath}"
答
您可以使用Open3
模块(manual)它返回3个对象:标准输入,标准输出,标准错误
但是,你是不是能够保持输出和错误之间的顺序。
例子:
#include <stdio.h>
int main(int argc, char *argv[]) {
fprintf(stdout, "Normal output\n");
fprintf(stderr, "Error output\n");
fprintf(stdout, "Normal output\n");
}
被捕获为:
Normal output
Normal output
Error output
如何维持秩序的唯一方法是运行程序的两倍。 :-(
样品Ruby代码:
#!/usr/bin/env ruby
require 'open3'
require 'pathname'
logfile = ARGV.first()
cmd = ARGV.drop(1).join(" ")
dir = Pathname(logfile).dirname
if not File.directory?(dir)
Dir.mkdir(dir)
end
file = File.open(logfile, "w")
stdin, stdout, stderr = Open3.popen3(cmd)
stdin.close()
file.puts(stdout.read())
error = stderr.read()
file.puts(error)
puts error
file.close