エラーが発生する可能性のあるコマンドを実行しています。
cmd sub-cmd --param1 value1 --param2 value2
このコマンドはエラーを返す可能性があります。エラーメッセージは、特定の文字列で終わる特定のエラーメッセージです(開始は異なりますが、終了は常に同じです)。cmd
特定の文字列で終わるエラーメッセージが特定の回数(5回など)に返される場合は、同じコマンドを再試行するための小さなシェルスクリプトコードを探しています。また、パラメータが許可されていることに注意してくださいcmd
。私はシェルスクリプトが私が何でも渡すことができるようにしたいですcmd
。エラーメッセージが私が探しているメッセージではない場合、シェルスクリプトはエラーを返して停止します(exit(1)
)。ありがとうございます。
答え1
その後、コマンドの出力をキャプチャする必要があります。すべてをキャプチャできる場合(または標準出力を無視できる場合)、最も簡単です。
#!/bin/bash
errormsg=$( cmd "$@" 2>&1 >/dev/null )
re="known error message$"
if [[ $errormsg =~ $re ]]; then
echo "cmd failed with known message
fi
その中のコマンド置換$(..)
とリダイレクトはコマンドの標準エラー出力をキャプチャし、エラーではなく出力にリダイレクトします。次に、文字列の終わりが文字列の終わりを表す正規/dev/null
表現と比較します。$
(コマンド置換は末尾の改行を削除するため、正規表現はこれらの改行と一致する必要はありません。)スクリプト"$@"
の引数に拡張して引数として渡しますcmd
。
もちろん、プログラムを繰り返し実行するにはループが必要です。コマンド置換の代替手段は、一時ファイルを使用してエラー出力を保存して後で表示することです。また、コマンドの標準出力を表示する方が簡単になるので、次のようにしましょう。
#!/bin/bash
re="known error message$"
retries=0
max_retries=5
errorfile=$(mktemp) # temp file for the errors
trap 'rm "$errorfile"' EXIT # remove the temp file on exit
while cmd "$@" 2> "$errorfile"; # run the command
ret=$?; # save the exit code
[[ $( < $errorfile ) =~ $re ]]; do # check the output
cat "$errorfile" >&2 # print the errors to
# the script's stderr, too
retries=$((retries+1)) # retry a couple of times
echo -n "cmd failed with known message"
if [[ $retries -lt $max_retries ]]; then
echo ", retrying."
else
echo ", exit."
exit 1
fi
done
cat "$errorfile" >&2
echo "cmd completed with status $ret"; # use saved exit code, since it might
exit "$ret" # have failed for other reasons
(while cmd1; cmd2; do ...
走るガイドライン1最初に実行してからガイドライン2ループ条件として。 )
上記では、コマンドの実際の終了状態を無視し、出力のみを調べました。終了状態を考慮するには、スクリプトを変更する必要があります。