私のcrontabにはサービスを監視するコマンドがあります(具体的には私のWebサイトのTorバージョンにまだアクセスできることを確認してください)。サイトにアクセスできる場合は監視コマンドが成功し、そうでなければ失敗します(電子メールを受信します)。ただし、断続的なTorの中断は時々電子メールを受け取り、ダウンタイムはかなり短いです。
私のcrontabのこの監視コマンドが連続して何度も(例えば10回)失敗した場合は通知を受けたいので、ダウンタイムが長くなったときにのみ通知を受け取ります。
もちろん、これを行うためにカスタムスクリプトを作成し、一時ファイルに失敗した回数を保存するなどの作業を実行できますが、これは非常に一般的な要件のように見えるので、すでに標準的なソリューション(同じファイルに)がある可能性があると思いました。 。 (中) そうですね。その他のユーティリティ'chronic
似ていますが、他の目的を提供するためにすでに存在しています。 )
最後の10回の呼び出しが失敗しない限り、問題が実行されwrapper COMMAND
成功するようにするラッパースクリプトはありますか?この場合、最後のエラーコードと失敗した呼び出しの出力を返す必要がありますか?COMMAND
COMMAND
答え1
次のスクリプトは、説明する内容のラッパーとして使用できます。指定されたコマンドの標準出力と標準エラーストリームをステータスディレクトリ($HOME/states
)に保存し、失敗した実行数を保存します。
コマンドが10回以上(またはコマンドラインフラグで指定された数だけ-t
)実行に失敗すると、標準エラーストリームにいくつかの出力が提供されます。他のすべての場合、出力は提供されません。スクリプトは、与えられたコマンドと同じ終了状態で終了します。
使用例:
$ sh ./script.sh -t 2 sh -c 'echo "this will fail"; cd /nowhere'
$ sh ./script.sh -t 2 sh -c 'echo "this will fail"; cd /nowhere'
FAILED 2 times: sh -c echo "this will fail"; cd /nowhere
f88eff95bba49f6dd35a2e5ba744718d
stdout --------------------
this will fail
stderr --------------------
sh: cd: /nowhere - No such file or directory
END
スクリプト自体(md5sum
GNU coreutilsに依存):
#!/bin/sh
statedir="$HOME/states"
if ! mkdir -p "$statedir"; then
printf 'Failed creating "%s"\n' "$statedir" >&2
exit 1
fi
max_tries=10
while getopts 't:' opt; do
case "$opt" in
t) max_tries=$OPTARG ;;
*) echo 'error' >&2
exit 1
esac
done
shift "$(( OPTIND - 1 ))"
hash=$( printf '%s\n' "$@" | md5sum | cut -d ' ' -f 1 )
"$@" >"$statedir/$hash".out 2>"$statedir/$hash".err
code=$?
if [ -f "$statedir/$hash" ]; then
read tries <"$statedir/$hash"
else
tries=0
fi
if [ "$code" -eq 0 ]; then
echo 0 >"$statedir/$hash"
exit 0
fi
tries=$(( tries + 1 ))
printf '%d\n' "$tries" >"$statedir/$hash"
if [ "$tries" -ge "$max_tries" ]; then
cat >&2 <<END_MESSAGE
FAILED $tries times: $@
stdout --------------------
$(cat "$statedir/$hash".out)
stderr --------------------
$(cat "$statedir/$hash".err)
END
END_MESSAGE
fi
exit "$code"