シェルスクリプトの通常のように、stdoutを1つのファイルに、stderrを別のファイルに、stdout + stderrを3番目のファイルに保存し、stdout + stderrをターミナルに保存するにはどうすればよいですか?
私はこれを他の場所で見つけました:
exec > >(tee std_out) 2> >(tee err_out >&2)
ls # Should got to std_out
fsdfs # Command not found goes to err_out
本当に近いです。 bash test.sh 2>&1 | tee output
その後は機能しますが、スクリプトの実行方法にアクセスできません。これは、cicdシステムです。 execを使用してスクリプト内から「結合出力」を実行できるようにする必要があります。
CI/CDライブラリを作成していますが、クライアントがライブラリを使用する目的がわからないので、それぞれの使用例を説明します。
単にアプローチを拡張する:
_exec 2> >(tee -a stderr stdall) 1> >(tee -a stdout stdall)
_
標準エラーはstderr
という名前のファイルに書き込まれ、標準出力はstdout
に書き込まれます。また、標準エラーと標準出力の両方がコンソールに書き込まれます(または2つのファイル記述子が時間exec
が実行されます)とstdall
まで。
_tee -a
_(追加)は、stdall
が書き込みを開始する2番目のtee
によって上書きされないようにするために必要です。
リダイレクトが実行される 順序 が関係することに注意してください。2番目のプロセス置換は最初のリダイレクトの影響を受けます。つまり、それが発生したエラーは>(tee -a stderr stdall)
に送信されます。もちろん、この副作用を回避するために、2番目のプロセス置換の標準エラーを_/dev/null
_にリダイレクトできます。標準エラーの前に標準出力をリダイレクトすると、すべてのエラーがstdout
およびstdall
にも送信されます。
Bashのプロセス置換のコマンドは 非同期 で実行されるため、出力が生成順に表示されることを保証する方法はありません。さらに悪いことに、標準出力と標準エラーのフラグメントは、同じ行に表示される可能性があります。
スクリプトは、bashの> >(...)
構成に依存する代わりに、_$0
_(無限再帰を回避するために環境変数を設定および確認する)を介して自分自身を実行できます。IMLEは気まぐれで信頼性が高くありません。
_if [ "$REDIRECTED" != 1 ]; then
export REDIRECTED=1
set -o pipefail
{ { "$0" | tee stdout >&3; } 2>&1 | tee stderr; } 3>&1 | tee stdboth
exit
fi
# rest of your script here
_
tee
はラインバッファリングを使用しないため(stdbuf(1)
を使用して強制することもできません)、stdoutとstderrに書き込まれるデータの順序は最終出力では考慮されません。フルバッファリングを使用し、stdoutとstderrの両方に書き込むコマンドでは、ラインバッファリングtee
は役に立たず、さらに悪いことに、出力行がstdoutとstderrの半分になる場合があります。
シェル言語とすぐに利用できるコマンドラインユーティリティを使用するだけで問題が解決することはないと思います。
CI/CDライブラリを作成していますが、クライアントがライブラリを使用する目的がわからないので、それぞれの使用例を説明します。
これがシナリオであることを考えると、出力を処理するためのbashの必要性について質問します。このコンテキストで理想的には、出力にタイムスタンプを付けて標準出力タイプのIDを指定し、アプリケーションがメッセージの処理方法を決定するアプリケーションである必要があります。