2011-03-01 83 views
0

我可以做這樣的事情在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腳本將完成兩兩件事:

  1. 結果在一個簡單的語句與更少的重定向技巧和只有一個單一的日誌文件的規範。
  2. 如有必要,創建日誌文件夾。

我在看Ruby的popen和spawn選項,但我沒有看到將STDERR流拆分爲兩個目標的方法。

回答

0

此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}" 
0

您可以使用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 
0

使用Ruby嘗試this article有關實現類似的功能tee 。你應該可以用它作爲你的shell代碼的純紅寶石(或至少不含exec)實現的起點。

相關問題