如何忽略 cron 运行的脚本中的暂时性失败?

如何忽略 cron 运行的脚本中的暂时性失败?

我有各种备份样式的脚本,它们通常按每日计划从无头服务器(Ubuntu 14.04)上的 cron 运行。 Cron 配置了邮件服务器,因此我可以从作业中获取反馈。通常,这些备份脚本被编写为成功运行时没有任何 stdout/stderr 输出(遵循“没有消息就是好消息”的标准 Unix 范例),这样它们就不会用大量垃圾堵塞我的电子邮件收件箱。

有时这些会失败,我会立即收到一封包含 stdout/stderr 输出的邮件。然而,这些失败往往是为了已知原因,特别是短暂的(即它们可能会在第二天再次消失)。例如,我的互联网连接有点不可靠,有时远程 DNS 解析会失败(假设就本问题而言这是无法修复的)。当然,这无法提前预测,因此降低工作频率是行不通的。

我想我希望 cron 仅在特定作业失败超过n尝试,或在一段时间后,所以我只能得到我需要解决的“永久”错误的报告。那可能吗?

我在 Ubuntu 14.04 上使用 cron 3.0pl1-124ubuntu2,尽管我对其他类似 cron 的软件持开放态度,而且更通用的答案(例如,我可以在脚本周围放置一个包装器)对其他人来说非常有用,我确信。

我考虑过的选项:

  • 将逻辑合并到脚本本身中来处理这个问题 - 一个选项,但我一直在寻找更通用的地方 - 有些脚本是 bash,有些脚本是 python 等。此外,这会使事情变得非常复杂,因为脚本中的所有 stdout/stderr确实需要坐在包装函数中。
  • 使用持续集成服务器,例如詹金斯处理运行我的作业 - 更强大,可能提供我正在寻找的各种插件,但管理起来明显更复杂,有点重量级(需要 JVM),并且不是很 Unix-y。
  • 没有理由- 有点过于激进,因为它会重试远程备份等,这会占用资源并可能导致意外 DoS。我宁愿按照原来的计划重试 cron 作业。

答案1

因为您想要跟踪多天的故障,所以您本质上需要记录问题,但是这些“日志”不必关心您,并且可以仅为 cronjob 隐藏。对脚本进行包装似乎是正确的选择。

maxAttempts=5

if [ -f ~/.script_fails ];then #determine the number of failures
    failures=$(cat ~/.script_fails)
else
    failures=0
fi

if [ $failures -lt $maxAttempts ];then #determine if failures exceeds max attempts
    ./script.sh > /dev/null #if so, get rid of output
else
    ./script.sh #otherwise keep it
fi

result=$?

if [ $result -eq 0 ];then #increment or remove counter
    rm ~/.script_fails
else
    failures=$failures + 1
    echo $failures > ~/.script_fails
fi

这决定了何时需要保留或忽略日志记录,相当简单。用于跟踪失败计数的文件隐藏在您的主目录中,因此您可以根据需要进行检查,但您的邮件不应该看到任何内容,除非失败次数太高。

不过,我绝对推荐使用 jenkins,配置后它会让生活变得更轻松。

答案2

我现在开始编写一个包装实用程序来解决我自己的问题,称为克罗默。现在它正在以基本形式运行。欢迎任何贡献/拉取请求/问题等。

相关内容