Linux中的Cron作业测试和调试
1. 概述
Cron 作业 在不同于我们正常 shell 的环境中执行,这可能是各种错误和挫折的根源。 在本教程中,让我们来看看我们可以采取的一些措施,以便更轻松地调试我们编写的 cron 作业。
本文中提到的所有命令都是 POSIX 命令,并在 Bash 中进行了测试。它们应该在每个 POSIX 兼容的 shell 中都可用。
2. 挑战
使测试和调试 cron 作业变得困难的问题是它们在与我们自己不同的环境中执行。我们需要对这些差异有一个很好的理解来应对这种情况。
2.1. 用户
位于这些目录中的 Cron 作业以 root 身份运行:
/etc/cron.hourly/
/etc/cron.daily/
/etc/cron.weekly/
/etc/cron.monthly/
我们也可以将它们放在一个 cron 表中,或者简称为*crontab *。每个用户都有自己的 crontab。crontab 中定义的所有作业都以拥有它的用户身份运行。
为了成功编写这些作业,我们必须以 cron 守护程序将使用的同一用户身份编写和测试它。
我们应该始终使用crontab命令来编辑 crontab,因为它会检查我们表达式的语法。
2.2. 环境
Cron 作业在几乎空旷的环境中运行。守护进程设置了一些变量和一个仅包含 /usr/bin:/bin的最小PATH。
我们应该始终在 cron 作业中使用绝对路径,而不是依赖HOME和PATH的内容,或者我们应该在脚本中明确定义PATH。
3. 记录
与我们系统上运行的大多数守护程序一样,cron 守护程序将其输出记录在*/var/log*下的某处。我们检查这些日志以查看我们的作业是否在正确的时间执行。
最流行的 cron 实现是Vixie cron 。Vixie cron 日志转到*/var/log/cron*。这些日志显示作业何时执行,但它们无法告诉我们作业运行时是否发生错误。
此外,最好将日志记录添加到我们的脚本中。这将有助于准确找出问题所在。
命令printenv 和 Bash 内置命令set 结果证明是完美的。我们通过在脚本周围放置这些行来添加它们:
printenv
set -x
... our script goes here ...
set +x
printenv命令将所有环境变量打印到标准输出。
使用set -x,我们将 shell 置于一种模式,所有执行的命令也将打印到标准输出。最后,在脚本结束时,我们使用set +x关闭此调试模式。
4. 快速失败
说到它,没有什么比真实的更好。我们可以模仿 cron 守护进程所做的一切,但我们只能通过作业本身运行它来确保我们的作业按预期工作。
我们可以将我们的 cron 表达式 设置为未来非常近的时间,并将所有内容记录到文件中:
42 20 * * * /path/to/cronjob.sh > /tmp/cronjob.log 2>&1
我们的脚本将在 20:42 执行。我们通过使用* 2>&1 *将标准错误重定向到标准输出来捕获日志文件中的所有内容。