web-dev-qa-db-ja.com

bash:stderrをファイルにリダイレクトし、stdout + stderrを画面にリダイレクトする

コマンドのstderrストリームをログファイルに保存したいが、出力全体(stdout + stderr)も画面に表示したい。これどうやってするの?

Stdout + stderrをコンソールに表示し、両方のストリームをファイルにリダイレクトするための解決策だけを見つけました:

 foo | tee output.file

https://stackoverflow.com/questions/418896/how-to-redirect-output-to-a-file-and-stdout

しかし、私はstderrをログファイルにリダイレクトしたいだけです。

6
linuxguy

最近のbashでは、プロセス置換を使用できます。

foo 2> >(tee stderr.txt)

これは、tderを実行しているプログラムにstderrを送信するだけです。

よりポータブルに

exec 3>&1 
foo 2>&1 >&3 | tee stderr.txt

これにより、ファイル記述子3が現在のstdout(つまり、画面)のコピーになり、パイプを設定してfoo 2>&1 >&3を実行します。これにより、fooのstderrがパイプである現在のstdoutと同じ場所に送信され、次にstdoutが元の出力であるfd 3に送信されます。パイプは、fooの元のstderrをteeにフィードします。これにより、それがファイルに保存され、画面に送信されます。

7
icarus

私が見つけることができる最良の答え: ここ

(cmd 2> >(tee /dev/stderr)) > log

両方(stdoutおよびstderr)を両方(screenおよびfile)にパイプし、次の場合にエラーをキャプチャします。インライン条件(if)または連続するインラインコマンドで使用されます。

例:

$((curl "https://unix.stackexchange.com"  2> >(tee /dev/stderr)) >> logfile) && echo "some other commands if curl succeeds without error"

そのようなティーへのパイプのような他のメソッドでは(tee ...)、次のコマンド(echo ...)が実行されます(curl )成功または失敗、(tee)は(curl)ではなく、最後に実行されたコマンドと見なされるため

0
Enim