bashの:リダイレクト(および追加)stdoutとstderrファイルと端末との適切な終了ステータスを取得します
質問
は、ファイルにstdoutとstderrをリダイレクト(および追加)するには、私は次の操作を行います。
command 2>&1 | tee -a file.txt
しかし、私は終了状態の正確な値を得ることをこのように操作を行うための別の方法は何ですか?
それは私が$?
をテストする場合、私はcommand
の終了ステータス、tee
のない終了ステータスを見たいと思って、である。
私は私が代わりに${PIPESTATUS[0]}
のここ$?
を使用することができることを知っているが、私はPIPESTATUS
をチェックする必要が伴わないと、別の解決策を探しています。
解決
おそらく、あなたは$?
にPIPESTATUSから終了値を入れることができます。
command 2>&1 | tee -a file.txt ; ( exit ${PIPESTATUS} )
他のヒント
別の可能性としては、いくつかのbash
の風味と、pipefail
オプションをオンにすることです。
pipefail
設定した場合は、は、パイプラインの戻り値があります 最後(右端)の値 非ゼロで終了するためのコマンド 状態、またはゼロのすべてのコマンドであれば 成功したパイプラインの出口。この オプションはデフォルトでは無効になっています。
set -o pipefail
...
command 2>&1 | tee -a file.txt || echo "Command (or tee?) failed with status $?"
この(それはまた、POSIXのPIPESTATUS
で作業したいので、例えば)移植性、sh
の機能を実現する唯一の方法を言われたそれは、を必要とする。すなわち、ビット複雑である一時ファイルのパイプを伝播しますバック親シェルプロセスに終了ステータスます:
{ command 2>&1 ; echo $? >"/tmp/~pipestatus.$$" ; } | tee -a file.txt
if [ "`cat \"/tmp/~pipestatus.$$\"`" -ne 0 ] ; then
...
fi
や、再利用のためにカプセル化:
log2file() {
LOGFILE="$1" ; shift
{ "$@" 2>&1 ; echo $? >"/tmp/~pipestatus.$$" ; } | tee -a "$LOGFILE"
MYPIPESTATUS="`cat \"/tmp/~pipestatus.$$\"`"
rm -f "/tmp/~pipestatus.$$"
return $MYPIPESTATUS
}
log2file file.txt command param1 "param 2" || echo "Command failed with status $?"
または、より一般的に、おそらく
save_pipe_status() {
STATUS_ID="$1" ; shift
"$@"
echo $? >"/tmp/~pipestatus.$$.$STATUS_ID"
}
get_pipe_status() {
STATUS_ID="$1" ; shift
return `cat "/tmp/~pipestatus.$$.$STATUS_ID"`
}
save_pipe_status my_command_id ./command param1 "param 2" | tee -a file.txt
get_pipe_status my_command_id || echo "Command failed with status $?"
...
rm -f "/tmp/~pipestatus.$$."* # do this in a trap handler, too, to be really clean
使用プロセス置換ます:
command > >( tee -a "$logfile" ) 2>&1
Tシャツはとても$サブシェルで実行されますか? のコマンドのの終了ステータスを保持します。
これを行うの難解なPOSIXの方法があります:
exec 4>&1; R=$({ { command1; echo $? >&3 ; } | { command2 >&4; } } 3>&1); exec 4>&-
これはその出力親シェルの出力にリダイレクトされ、R
するcommand1
の戻り値、及びcommand1
のパイプ出力に変数command2
を設定します。