为什么我的 cronjob 在糟糕的一天启动?

为什么我的 cronjob 在糟糕的一天启动?

我想在每个月初开始一项工作,但只在工作日。

为此,我在 /etc/crontab 文件中添加了此行:

7 0 3-5 * 1-5  root  ( test "`date '+\%d'`" = "03" || test "`date '+\%u'`" = "1" ) && /path/to/my/script.sh

预期结果:script.sh 在每月 3 号到 5 号之间的第一个工作日启动(“测试”部分只是为了确保它启动一次)。

它运行得很好,本月 3 号,cronjob 就运行了。

但不幸的是,出于未知原因,它也在今天(6 月 8 日,星期一)启动了。我可以理解“测试”部分有效(test "date '+%u'" = "1"是真的,而且合乎逻辑),但“cron”部分不应该是真的(7 0 3-5 * 1-5不是真的,我们是 8 号)。

所以我想知道,我做错了什么吗,或者是否存在更深层次的问题?

谢谢!

答案1

这种确实令人惊讶的行为记录在man 5 crontab(重点是我的):

当分钟、小时和月份字段与当前时间匹配时,cron(8) 会执行命令,什么时候最后一个两个日期字段(月份中的日期或星期几)与当前时间匹配(见下文“注释”)。

[...]

注意:命令执行的日期可以通过两个字段指定 - 月份日期和星期几。如果两个字段都受到限制(即不是 *),
当任一字段与当前时间匹配时,命令将运行
例如,“30 4 1,15 * 5”将导致命令在每个月 1 日和 15 日以及每个星期五的凌晨 4:30 运行。

因此,您需要做的是让您的命令测试时间。就像您让它只运行一次一样。由于这变得有点复杂,我建议在您的脚本本身中完成检查,然后在相关月份的每一天启动 cron 命令。类似

## Check if this is a weekday 
[ $(date '+%u') -le 5 ] && [ $(date '+%u') -ge 1 ] || exit;
## Make sure it only runs once. If yesterday was also a weekday and 
## date >=3 and <=5, we can assume the script ran then and should exit. 
[ $(date -d yesterday '+%u') -le 5 ] && [ $(date -d yesterday '+%u') -ge 1 ] && 
 [ $(date -d yesterday '+%d') -le 3 ] && [ $(date -d yesterday '+%d') -ge 5  ] && exit;
## Rest of your script goes here
[...]

然后,从 开始cron,仅在每个月的第 3 至 5 天启动您的脚本:

7 0 3-5 * *  /path/to/my/script.sh

相关内容