POSIX 关于非星号月份和星期几的 crontab 是否错误?

POSIX 关于非星号月份和星期几的 crontab 是否错误?

背景

众所周知,UNIX cron 在以下情况下运行作业:任何一个每月的某一天或者星期几匹配,如果两者都使用显式值而不是星号通配符指定:

0 0 * * 1     # every Monday
0 0 1 * *     # every month's first day
0 0 1 * 1     # every Monday *and also* every month's first day
0 0 1 * 1-7   # every day
0 0 1-31 * 1  # every day

请注意这些常见示例都包含*月份字段。

非星号月份的 POSIX

POSIX 规范实际上是这么说的crontab(强调我的):

可以通过两个字段(月份中的日期和星期几)来指定日期。如果月、月中的某一天、星期几都是<星号>字符,则每天都将被匹配。如果月份或月份中的某一天被指定为元素或列表,但星期几是 <asterisk>,则月份和月份中的某一天字段应指定匹配的日期。如果月份和一个月中的某一天被指定为 <asterisk>,但一周中的某一天是一个元素或列表,则只有一周中指定的几天匹配。最后,如果月份或月份中的某一天指定为元素或列表,星期几也指定为元素或列表,然后任意一天匹配月份和月份中的某一天,或者星期几,应匹配。

这似乎声明以下时间表将匹配任何一个或者星期几:

0 0 * 1 1     # every month's every Monday *and also* every day in January
0 0 * 1-12 1  # every day
0 0 1 1 1     # every month's every Monday *and also* 1 January

实践中的非星号月份

据我所知,没有任何常见的现代或历史 cron 实现实际上做到了这一点,包括SVR4 计划任务(这一定是首先匹配月份中的某一天或者星期几)及其后代开放Solaris伊卢莫斯维克西·克朗及其后代克罗尼自由BSD,开放BSD,网络BSD,蜻蜓BSD苹果系统cron 以及BusyBox crond

相反,所有这些实现始终需要月份字段的匹配,无论任何字段采用什么形式,并且仅根据两个月份日期和星期几字段是否更改其日期匹配逻辑包含*或显式值列表:

0 0 * 1 1     # every Monday in January
0 0 * 1-12 1  # every Monday
0 0 1 1 1     # every Monday in January *and also* 1 January

(或者在 BusyBox 的情况下,基于字段是否包含完整值范围或严格子集,无论使用什么语法)

规格错误?

POSIX 规范中描述的行为实际上在任何地方都实现了吗?如果提交缺陷报告,描述是否是规范中的错误,可以更正?为什么现在这样措辞背后有什么故事吗?

答案1

数字Unixv4(又名OSF1)实现了这个(存档手册页在这里):

您可以在两个字段(每月的某一天和每周的某一天)中指定执行命令的日期。您可以指定两个字段,也可以仅指定一个字段。要仅使用一个字段来指定日期,另一字段应包含星号 (*)。如果使用这两种方法,则只要满足任一规范,就会执行该命令。

也是如此索拉里斯正确的,虽然手册页的文本缺乏清晰度(并且一直如此),示例 3 清楚地说明了预期的行为:

示例 3 指定月份和星期的天数

此示例在每个月的第一天和第十五天以及每个星期一运行命令:

0 0 1,15 * 1

狄龙crond解释* * 2 * mon为“该月的第二个星期一”,虽然有用,但也是非标准的。答案在问题已链接@thanasisp 的作者在这一点上阅读起来很有用。 “或”行为来自系统V R2(约 1985 年)至少如此。

我发现在阅读 Open Group 文档时需要注意

  • 某些单词在某些上下文中的迂腐含义,就像 RFC 一样,但更是如此
  • 由 ⌦ ... ⌫ 符号界定的文本部分(这是一种不寻常的约定,因为这些符号可以向前和向后删除)

crontab 参考中的文本被标记,指示了部分的[UP] ⌦ ... ⌫可选行为(for )crontab -e用户 ortable Utilities,“输入文件”部分没有任何此类标记。

最后,如果月份或月份中的某一天被指定为元素或列表,并且星期几也被指定为元素或列表,则与月份和月份中的某一天或星​​期几匹配的任何一天,匹配。

我强调了“应”这个词,毫无疑问:

对于符合 POSIX.1-2017 的实现,描述强制的功能或行为。应用程序可以依赖功能或行为的存在。

对于应用程序或用户,描述强制的行为。

但是,作为系统管理员,我倾向于考虑规范抽象,它不可能是错误的(除非它错误到无法实现)。错误(如果有的话)是在实现中,如果它不符合所声明的规范(对于那些POSIXLY_CORRECT为了理智或利益而扭曲规范的实现者来说,这可能是通常的出狱之举。用户期望)。

相关内容