コマンドが連続して何度も失敗した場合、crontabは警告します。

コマンドが連続して何度も失敗した場合、crontabは警告します。

私のcrontabにはサービスを監視するコマンドがあります(具体的には私のWebサイトのTorバージョンにまだアクセスできることを確認してください)。サイトにアクセスできる場合は監視コマンドが成功し、そうでなければ失敗します(電子メールを受信します)。ただし、断続的なTorの中断は時々電子メールを受け取り、ダウンタイムはかなり短いです。

私のcrontabのこの監視コマンドが連続して何度も(例えば10回)失敗した場合は通知を受けたいので、ダウンタイムが長くなったときにのみ通知を受け取ります。

もちろん、これを行うためにカスタムスクリプトを作成し、一時ファイルに失敗した回数を保存するなどの作業を実行できますが、これは非常に一般的な要件のように見えるので、すでに標準的なソリューション(同じファイルに)がある可能性があると思いました。 。 (中) そうですね。その他のユーティリティ'chronic似ていますが、他の目的を提供するためにすでに存在しています。 )

最後の10回の呼び出しが失敗しない限り、問題が実行されwrapper COMMAND成功するようにするラッパースクリプトはありますか?この場合、最後のエラーコードと失敗した呼び出しの出力を返す必要がありますか?COMMANDCOMMAND

ベストアンサー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

スクリプト自体(md5sumGNU 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"

おすすめ記事