例如.如果你写
* * 13 * 5 command
该命令将在每个星期五和每月的第13天执行,而不仅仅是在星期五的第13天.
这与其他字段的格式相矛盾(当您编写30 2 * * *时,它将仅在小时和分钟时执行 – 正是您指定的;除了DoW和DoM之外的所有其他字段都相同).
所以我的问题是:这个例外是否有特定的原因?我的意思是,应该有一个理由,但我似乎无法找到它. (相反,我看到互联网中的很多人都希望像其他任何一样对待这些领域 – 使用“AND策略”,正好适用于“星期五13日”或“5月2日星期四”等事情.)
解决方法
在Paul Vixie写下他的cron替补之前,BSD cron就像是SysIII及其早期的cron.所有5个字段都是ANDed. 4.4后的BSD采用了Vixie cron,使自己更像SysV.
所以不要问(责备)Vixie.他刚刚克隆了SysV.
为什么SysV这样做?我不知道,但我会尝试提供一些部分线索……
为了尝试理解SysV中发生的事情,有助于查看源(before – SysIII和after – SVr4)以及新行为的文档:
Note: the specification of days may be made by two fields (day of the month and day of the week). If both are specified as a list of elements,both are adhered to.
(摘自SunOS 4.1.3手册页.在这个区域似乎是SysV-ish.在Paul Vixie写下他的替补之前,BSD cron从未有过这种行为.)
“两者都遵守”是使用AND和OR的普通布尔表达式的混乱替代.几十年后,它仍然出现在OpenSolaris手册页中:
The specification of days can be made by two fields (day of the month and day of the week). Both are adhered to if specified as a list of elements.
SysV代码是完全重写的.它的一个特点是,当没有工作即将运行时,它会长时间睡眠. (较旧的cron每分钟唤醒并将当前时间与所有工作规范进行比较.)计算功能(next_time)顶部的注释说明:注意:此例程很难理解.
这确实很难理解.它是“查找此crontab行的下一个执行时间”函数,而不是“决定当前时间是否与此crontab行匹配”函数,因此需要花费一些精力才能确定此函数中隐含的匹配规则,mday和wday都是非*,是(月和小时和分钟AND(mday或wday)).
基于此,结合文档避免明确告诉我们mday匹配和wday匹配之间的布尔关系的方式,我会猜测编写新cron的人并没有在这些术语中考虑它.他们不考虑5个布尔值的组合(直接对应于struct tm中的5个字段),而是关于一组4个问题:
>这是正确的月份吗?
>这是正确的一天吗?
>这是正确的时间吗?
>这是正确的分钟吗?
这自然导致在将其他所有内容组合在一起之前,以自己的方式组合日比较.也许SysV的cron作者刚刚做了当时显而易见的事情,没有检查与旧cron的兼容性或者像“每个月的第一个星期六”这样的用例.