bashを使用して、stderrとstdoutをログファイルにコピーし、コンソールに表示したままにするにはどうすればよいですか?
execを使用して、スクリプト自体の中でこれを実行したいと思います。
私が試した
exec &>> log.out
echo "This is stdout"
echo "This is stderr" >&2
しかし、上記はコンソールに何も出力しません。どうすればこれをbashで実現できますか?
bashを使用して、stderrとstdoutをログファイルにコピーし、コンソールに表示したままにするにはどうすればよいですか?
execを使用して、スクリプト自体の中でこれを実行したいと思います。
私が試した
exec &>> log.out
echo "This is stdout"
echo "This is stderr" >&2
しかし、上記はコンソールに何も出力しません。どうすればこれをbashで実現できますか?
回答:
あなたが探していtee
ます。
詳細man tee
については、を参照してください。
と組み合わせるにはexec
、プロセス置換を使用する必要があります。(詳細はman bash
を参照してください。)
exec &> >(tee log.out)
echo "This is stdout"
echo "This is stderr" >&2
exec 2>&1 | tee -a log.out
だけでは、コンソール上のログファイルには何も出力しません。多分私は正しい構文を使用していませんか?
tee
と組み合わせて書きました。
the-script | wc -l
、たとえば誰かがそうした場合、エラー行もカウントされ、エラーは表示されません。
できるよ:
: > log # empty log file if necessary
{ { {
...the script
} 3>&- | tee -a log >&3 3>&-
exit "${PIPESTATUS[0]}"
} 2>&1 | tee -a log >&2 3>&-
} 3>&1
exit "${PIPESTATUS[0]}"
次のように書くこともできます。
: > log # empty log file if necessary
exec 2> >(tee -a log >&2) > >(tee -a log)
...the script
しかし、bashは>(...
)で始まるプロセスを待機していないため、コマンドが返された後、端末に「tostop」属性があると、さらに厄介な効果(出力を静かに破棄するなど)になる可能性がある何かを端末に出力するという厄介な影響があります。オンです。
いずれの場合でもstdout
、両方のソリューションでパイプを作成することにより、2つのコマンドが独立して出力メッセージとエラーメッセージを出力するため、これは出力バッファリングと、出力メッセージとエラーメッセージの表示順序に影響します。
tee -a log >&2 3>&-
私はこれが古い投稿であることを知っていますが、なぜこれをしないのですか?
echo "hi" >> log.txt #stdout -> log
echo "hi" | tee -a log.txt #stdout -> log & stdout
echo "hi" &>> log.txt #stdout & stderr -> log
echo "hi" |& tee -a log.txt #stdout & stderr -> log & stdout
もちろん、標準出力が必要な場合は、定期的に印刷することもできます。
これは、これら2つの基本的なコマンドを使用するだけで、ストリームの任意の組み合わせで実行できます。
私がここに来て、理解/実装するのが簡単な答えが得られなかったことを知っています。うまくいけば、これは苦労している他の誰かの助けになるでしょう。
ちなみに、以前の自分のようなnoobsの場合、tee
コマンドが行うことは、stdin入力をstdoutと後続の引数として指定されたファイルの両方に出力することだけです。-a
追加の略なので、コマンドを使用するたびにファイルが上書きされることはありません。さらにご質問がありましたら、私が見つけ、これはすぐにはbashを学習するための非常に有用資源であることを。
これを行うもう1つの方法は、関数内でリダイレクトを使用することです。
#!/bin/bash
function1 () {
echo 'STDOUT from function 1'
echo 'STDERR from function 1' >&2
}
function2 () {
echo 'STDOUT from function 2'
echo 'STDERR from function 2' >&2
}
function3 () {
echo 'STDOUT from function 3'
echo 'STDERR from function 3' >&2
}
main() {
function1
function2
function3
}
main 2>&1 |tee log.txt
ここには、main
他のすべての関数を呼び出す関数があります。リダイレクトSTDOUT
してSTDERR
、main
関数をに変更しtee
ます。