我的 crontab 中有这样的条目:
0 0 1-2 * 1-6
它应该在周一到周六的 00:00(每月 1 号或 2 号)运行,对吗?例如,如果 1 号是星期日,那么它就不会运行,对吗?但它会在每月 2 号运行一个 cronjob,因为那天不是星期日。
答案1
如果该月的第一天是星期日,它确实会运行。
原因是两个条件“月份中的日期”(第三个字段)和“星期几”(第五个字段)不是通过 AND 连接(两个都必须发生),而是通过 OR 连接(其中一个必须发生)。来自man 5 crontab
:
注意:命令执行的日期可以通过两个字段指定——月份日期和星期几。如果两个字段都受到限制(即不是 *),则当任一字段与当前时间匹配时,命令就会运行。例如,“30 4 1,15 * 5”将导致命令在每个月 1 日和 15 日的凌晨 4:30 运行,以及每个星期五运行。
因此你的 cronjob 将在每月 1 号和 2 号的午夜运行另外每月的星期一、星期二、星期三、星期四、星期五和星期六。
如果您只需要在一个月内运行一次命令,而不是在周日运行,就像您在评论中所写的那样,那么您必须检查日期命令本身。
这些是运行该命令的条件:
IF (date is 1st day of month AND date is not Sunday)
OR (date is 2nd day of month AND yesterday was Sunday)
THEN run command
你可以写两个 cronjobs:
0 0 1 * * test $(date +\%u) -eq 7 || echo "today's the 1st day of the month but not Sun"
0 0 2 * * test $(date +\%u) -eq 1 && echo "today's Mon (=yesterday was Sun) and the 2nd day of the month"
第一个 cronjob 将会在每月 1 日的午夜运行:
date +%u
返回一个整数,其中 1 表示星期一,2 表示星期二,等等。('%' 需要逃脱在 crontab 中)。test
检查是否$(date +%u1)
等于7
(星期日)。||
是或布尔值操作符,它对前一个命令的返回值做出反应。如果test
返回 FALSE,则运行命令的其余部分。
第二个 cronjob 将会在每月第二天的午夜运行:
再次
date +%u
返回一个整数,其中 1 表示星期一,2 表示星期二,等等。test
检查是否$(date +%u1)
等于1
(星期一)。&&
是 AND布尔值运算符,如果test
返回 TRUE,则运行命令的其余部分。