現在、execを使用してstderrをエラーログにリダイレクトしています
exec 2>> ${errorLog}
唯一の欠点は、exec がテキストをログ ファイルに直接プッシュするだけなので、各実行をタイムスタンプで開始する必要があることです。stderr をリダイレクトする方法はありますが、タイムスタンプなどのテキストを追加できますか?
これは非常に興味深いです。bash をよく知っている人に聞いてみたところ、次のように答えてくれました。
foo() { while IFS='' read -r line; do echo "$(date) $line" >> file.txt; done; };
まず、stdin から 1 行の生の入力を読み取る関数を作成しますが、IFS への代入は空白を無視しません。1 行を読み取ると、適切なデータを先頭に追加して出力します。次に、stderr をその関数にリダイレクトするように bash に指示する必要があります。
exec 2> >(foo)
stderr に書き込むものはすべて、foo 関数を通過します。対話型シェルで実行すると、プロンプトが表示されなくなることに注意してください。これは、stderr に出力され、foo の読み取りが行バッファーされるためです:)
簡単に使用できます:
exec 1> >( sed "s/^/$(date '+[%F %T]'): /" | tee -a ${LOGFILE}) 2>&1
これは、プロンプトが表示されないという問題を完全に解決するわけではありません (パイプが一部のデータをキャッシュするため、短時間で表示されますが、リアルタイムでは表示されません...)。ファイル。
唯一の問題は、私が解決できなかったことです。これは、関数からこれを行うことです。これは、メインプログラムにとってexecが役に立たないサブシェルを開くためです...
この例では、元の stdout と stderr を失わずに stdout と stderr をリダイレクトします。また、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
これには最新の Bash バージョンが必要ですが、 Shellshockのおかげで、最近はこれに頼ることができます。
cat q23123 2> tmp_file ;cat tmp_file | sed -e "s/^/$(date '+[%F %T]'): /g" >> output.log; rm -f tmp_file