如果命令连续多次失败,则在 crontab 中发出警告

如果命令连续多次失败,则在 crontab 中发出警告

我的 crontab 中有一个命令来监视服务(具体来说,检查我的网站的 Tor 版本是否仍然可以访问):如果可以访问该站点,则该监视命令成功,否则失败(我会收到一封电子邮件)。然而,由于 Tor 间歇性故障,我时不时地收到电子邮件,而且停机时间相当短。

如果我的 crontab 中的此监控命令连续多次(例如 10 次)失败,我希望收到通知,因此只有较长时间的中断才会通知我。

当然,我可以编写一个自定义脚本来执行此操作,将失败次数存储在临时文件等中,但由于这看起来是一个非常常见的需求,我认为可能已经存在一些标准解决方案(在同一个文件中)那样更多实用程序'chronic已经存在以服务于类似但不同的目的。)

是否有一个包装器脚本,使得发出wrapper COMMAND将运行COMMAND并成功,除非最后 10 次调用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"

相关内容