2009-01-07 53 views
11

現在我使用EXEC標準錯誤重定向到一個錯誤日誌追加文本到stderr在bash

exec 2>> ${errorLog} 

唯一的缺點就是重定向,我要開始一個時間戳每次運行以來高管只是推文本直接進入日誌文件。有沒有辦法重定向stderr,但允許我附加文本,如時間戳?

回答

16

這非常有趣。我問,誰知道慶典相當不錯一個人,他告訴我這樣說:

foo() { while IFS='' read -r line; do echo "$(date) $line" >> file.txt; done; }; 

首先,創建了一個函數讀取從標準輸入原始輸入的一行,而分配給IFS使得它doesn」不要忽視空白。讀完一行後,它會輸出預先輸入的適當數據。然後,你必須告訴bash重定向標準錯誤信息到該功能:你寫到標準錯誤

exec 2> >(foo) 

現在一切都將通過foo的功能。注意當你在一個交互式shell中做這件事時,你將不會再看到提示,因爲它被打印到stderr,並且在foo中的讀取是行緩衝的:)

+0

$ foo(){while IFS =''read -r line;做echo「$(date)$ line」>> file.txt;完成; }; $ exec 2 >>(foo) 警告:程序'/ bin/bash'崩潰。 哎呦 – Peter 2012-04-19 11:56:12

+0

但如果我改變:echo 2 |發球>(foo),那麼它工作正常。 – Peter 2012-04-19 11:57:44

1

你可以簡單的只使用:

exec 1> >(sed "s/^/$(date '+[%F %T]'): /" | tee -a ${LOGFILE}) 2>&1 

這並不能徹底解決您就提示未顯示(ITT會後顯示問題很短的時間,但不是實時的,因爲管道會緩存一些數據......),但是會在標準輸出和文件中顯示1:1的輸出。

唯一的問題是,我沒能解決,就是從一個功能做到這一點,因爲這將打開一個子shell,其中EXEC是無用的主程序...

-1
cat q23123 2> tmp_file ;cat tmp_file | sed -e "s/^/$(date '+[%F %T]'): /g" >> output.log; rm -f tmp_file 
0

這示例重定向標準輸出和標準錯誤而不丟失原始標準輸出和標準錯誤。 stdout處理程序中的錯誤也會記錄到stderr處理程序中。文件描述符保存在變量中並在子進程中關閉。 Bash保重,沒有碰撞發生。

#! /bin/bash 

stamp() 
{ 
    local LINE 
    while IFS='' read -r LINE; do 
    echo "$(date '+%Y-%m-%d %H:%M:%S,%N %z') $$ $LINE" 
    done 
} 

exec {STDOUT}>&1 
exec {STDERR}>&2 
exec 2> >(exec {STDOUT}>&-; exec {STDERR}>&-; exec &>> stderr.log; stamp) 
exec > >(exec {STDOUT}>&-; exec {STDERR}>&-; exec >> stdout.log; stamp) 

for n in $(seq 3); do 
    echo loop $n >&$STDOUT 
    echo o$n 
    echo e$n >&2 
done 

這需要電流擊版本,但由於Shellshock一個可以依靠這個時下。