BASH スクリプト: 3 つの戻りコード/終了ステータスを取得して「グローバル終了」を実行しようとしています

BASH スクリプト: 3 つの戻りコード/終了ステータスを取得して「グローバル終了」を実行しようとしています

どこかからコピーした、機能する global_exit があります。これは 2 つのコマンド終了用です。強制的に失敗させるために 'echo' を 'ech' に名前変更すると、すべての組み合わせが機能することをテストできます。そして、ここではそれが機能します:

echo "$USER $(date +%F)" |& tee info.log
info_exit=${PIPESTATUS[0]}
echo "$USER $(date +%F)" |& tee list.log
list_exit=${PIPESTATUS[0]}

global_exit=$(( info_exit > list_exit ? info_exit : list_exit ))

if [ ${global_exit} = "0" ]; then
echo ">> SUCCESS <<"
elif [ ${global_exit} = "1" ]; then
echo ">> WARNINGS <<"
else
echo ">> FAILED <<"
fi
exit

これを 3 つの RC に拡張するにはどうすればよいでしょうか。この機能の使用方法に関するルールを見つけることができませんでした。以下を使用して推測しただけですが、同じテストのすべての組み合わせで機能するわけではありません (1 つの echo を 1 つずつ ech に名前変更して強制的に失敗させます)。

echo "$USER $(date +%F)" |& tee info.log
info_exit=${PIPESTATUS[0]}
echo "$USER $(date +%F)" |& tee list.log
list_exit=${PIPESTATUS[0]}
echo "$USER $(date +%F)" |& tee check.log
check_exit=${PIPESTATUS[0]}

global_exit=$((( info_exit > list_exit > check_exit ? info_exit : list_exit > check_exit )))

if [ ${global_exit} = "0" ]; then
echo ">> SUCCESS <<"
elif [ ${global_exit} = "1" ]; then
echo ">> WARNINGS <<"
else
echo ">> FAILED <<"
fi
exit

ありがとう :)

答え1

私の意図が正しく、記述されたとおりのコードを続行したい場合は、次のように変更します。

global_exit=$((( info_exit > list_exit > check_exit ? info_exit : list_exit > check_exit )))

これに:

global_exit=$((( info_exit > list_exit > check_exit ? info_exit : list_exit > check_exit ? list_exit : check_exit )))

設定どおり、info_exit が最大であれば正常に動作します。そうでない場合は、list_exit > check_exit かどうかに応じて、global_exit を 0 または 1 に設定します。追加の条件が追加されると、list_exit または check_exit の大きい方に設定されます。

答え2

0、1、その他すべての複数の戻りコードを一緒にチェックする方法の 1 つは、戻りコードを組み合わせることです。

echo "$USER $(date +%F)" |& tee info.log
exit_code=$((exit_code | PIPESTATUS[0]))
echo "$USER $(date +%F)" |& tee list.log
exit_code=$((exit_code | PIPESTATUS[0]))
echo "$USER $(date +%F)" |& tee check.log
exit_code=$((exit_code | PIPESTATUS[0]))

if (( 0 == exit_code )); then
  echo ">> SUCCESS <<"
elif (( 1 == exit_code )); then
  echo ">> WARNING <<"
else
  echo ">> FAILED <<"
fi

このアプローチでは、終了コードを区別できず、複数の戻りコードが発生する可能性がありますが、一般的な OK / NOT OK 戻りコードの場合はこれで十分です。

答え3

関数を使って確認することもできます全てステータス コードを取得しPIPESTATUS、最高値を保存します。

#!/bin/bash

max_exit=0

set_max_exit() {
  for i in "${PIPESTATUS[@]}"; do
    [ "$i" -gt "$max_exit" ] && max_exit=$i
  done
}

echo | grep x   # exit 1
set_max_exit

ech             # exit 127
set_max_exit

ls adfds        # exit 2
set_max_exit

if [ "$max_exit" -eq 0 ]; then
  echo ">> SUCCESS <<"
elif [ "$max_exit" -eq 1 ]; then
  echo ">> WARNING <<" >&2
else
  echo ">> FAILED <<" >&2
fi

exit "$max_exit"

出力:

$ ./script.sh
./script.sh: line 14: ech: command not found
ls: cannot access 'adfds': No such file or directory
>> FAILED <<
$ echo $?
127

関連情報