为什么crontab在指定月份和星期几时使用OR?

时间:2015-12-18 13:46:23

标签: linux unix cron crontab

这是一个着名的“问题”,当crontab行包含星期和月中的某一天时,cron使用OR来计算一天来触发命令。 例如。如果你写

* * 13 * 5 command

该命令将在每个星期五和每月的第13天执行,而不仅仅是在星期五的第13天。 这与其他字段的格式相矛盾(当您编写30 2 * * *时,它将仅在小时和分钟时执行 - 正是您指定的;除了DoW和DoM之外的所有其他字段都相同)。

所以我的问题是:这个例外是否有特定原因?我的意思是,应该有一个理由,但我似乎无法找到它。 (相反,我看到互联网中有很多人希望像其他任何一样对待这些领域 - 使用“AND策略”,正好适用于“星期五13日”或“5月2日星期四”等事情。)< / p>

3 个答案:

答案 0 :(得分:3)

再回到Vixie cron,System V cron中出现了“ wday OR mday”逻辑,但System III或更早版本中没有。

在Paul Vixie撰写cron替代人之前,BSD cron就像SysIII及更早的cron。所有5个字段都进行了AND运算。 4.4版之后的BSD采用了Vixie cron,使自己更像SysV。

所以不要问(怪罪)Vixie。他只是在克隆SysV。

SysV为什么要这样做?我不知道,但我会尽力提供一些线索...

要尝试了解SysV中发生了什么,它有助于查看源(before - SysIIIafter - SVr4)以及新行为的文档:

  

注意:可以通过两个字段(月中的某天和一周中的某天)来指定天数。如果将两者都指定为元素列表,则都将遵守。

(摘录自SunOS 4.1.3手册页。该区域似乎是SysV-ish。在Paul Vixie撰写他的替代书之前BSD cron从未有过这种行为。)

“两个都遵守”是使用AND和OR的普通布尔表达式的令人困惑的替代。几十年后,它仍在OpenSolaris手册页中显示:

  

可以通过两个字段(月中的天和周中的天)来指定天数。如果指定为元素列表,则都遵守。

SysV代码是完整的重写。它的功能之一是长时间没有作业要运行时会长时间睡眠。 (较早的cron每分钟都会醒来,并将当前时间与所有作业规范进行比较。)计算功能(next_time顶部的注释说明:NOTE: this routine is hard to understand.

确实很难理解。这是“查找此crontab行的下一次执行时间”功能,而不是“确定当前时间是否与此crontab行相匹配”功能,因此,即使在这种情况下,即使弄清楚该函数中隐含的匹配规则,也需要花费一些精力。 mdaywday都不是*,都是(month AND hour AND minute AND (mday OR wday))

基于此,再加上文档避免明确地告诉我们mday匹配和wday匹配之间的布尔关系的方式,我猜想写新cron的人并没有在考虑这些问题条款。他们不是在考虑5个布尔值的组合(直接对应于struct tm中的5个字段),而是在考虑4个问题:

  1. 现在是正确的月份吗?
  2. 今天正确吗?
  3. 现在是正确的时间吗?
  4. 现在是正确的分钟吗?

这自然会导致天比较以自己的方式进行组合,然后再将其他所有内容进行“与”运算。也许SysV cron作者只是做了当时感觉很明显的事情,而没有检查与旧cron的兼容性或思考“每月的第一个星期六”之类的用例。

答案 1 :(得分:0)

我在使用crontab中的许多脚本的Unix服务器上工作。我们可以非常方便地指出应该在一周中的一天运行的脚本上的特定日期。在我的情况下,我不明白为什么我会在一周的某一天运行一个预定的脚本,如果它是在13日,以你的例子为例。

答案 2 :(得分:0)

也许这不是一个让您满意的足够深的“为什么”(它肯定不能令我满意),但是一个简单的答案是“因为标准如此规定”。

具体来说,POSIX标准在http://pubs.opengroup.org/onlinepubs/9699919799/utilities/crontab.html中规定:

  

如果将月份中的月份或日期指定为元素或列表,并且还将一周中的日期指定为元素或列表,则与 一个月中的月份应匹配

(轰炸我的)。

我不知道为什么这是标准所要求的。有趣的是,甚至实现了Vixie Cron(在Ubuntu和MacOS上使用的Cron实现)的Paul Vixie都不知道 。在cron.c中有此评论:

/* the dom/dow situation is odd.  '* * 1,15 * Sun' will run on the
 * first and fifteenth AND every Sunday;  '* * * * Sun' will run *only*
 * on Sundays;  '* * 1,15 * *' will run *only* the 1st and 15th.  this
 * is why we keep 'e->dow_star' and 'e->dom_star'.  yes, it's bizarre.
 * like many bizarre things, it's the standard.
 */

因此,就其声音而言,即使您可能正在使用的Cron的执行器也无法比我给出的非解释更深入地了解问题的答案该答案的第一段。