質問

今、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 のおかげで信頼できますこれは最近です。

私はちょうど同じ小さな端正なものを探していました。この投稿を見た後、私も有望に見える別のアプローチを見ました: http: //utcc.utoronto.ca/~cks/space/blog/unix/PipingJustStderr

cat q23123  2> tmp_file ;cat tmp_file | sed -e "s/^/$(date '+[%F %T]'): /g" >> output.log; rm -f tmp_file 
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top