12

在每月的第二个和第四个星期六运行作业的 cron (linux) 语法是什么?

4

5 回答 5

26

该月的第二个星期六是从 8日到 14(含)的日期中的一个(也是唯一一个) 。同样,第四个星期六是在22 日28日之间的某个日期。

您可能认为您可以使用星期几字段将其限制为星期六(6在下面的行中):

0 1 8-14,22-28 * 6 /path/to/myscript

不幸的是,根据手册页,日期和星期几是一个 OR 命题,其中任何一个都会导致作业运行:

cron当分钟、小时和年中的月份字段与当前时间匹配时,以及当两个日期字段(月中的日或周中的日)中的至少一个与当前时间匹配时,将执行命令。

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

因此,您需要将您的cron工作设置为在这些日子的每一天运行,如果不是星期六,则立即退出。

cron条目是这样的:

0 1 8-14,22-28 * * /path/to/myscript

(每天凌晨 1 点运行)。

然后,在 的顶部/path/to/myscript,输入:

# Exit unless Saturday
if [[ $(date +%u) -ne 6 ]] ; then
    exit
fi

而且,如果您不能修改脚本(例如,如果它是一个程序),只需编写一个仅包含该检查和对该程序的调用的脚本,然后运行它cron

您还可以将星期六的测试放入crontab文件本身,以将调度数据全部保存在一个位置:

0 1 8-14,22-28 * * [ `date +\%u` = 6 ] && /path/to/myscript
于 2012-07-27T07:52:57.383 回答
13

扩展@paxdiablo 的回复,为什么不将添加内容放入 crontab 而不是脚本?

#m h dom       mon dow command
0  1 8-14,22-28 *   *   [ `date +\%u` = 6 ] && /path/to/myscript

请注意 %u 之前的反斜杠,当您在命令行上尝试此操作时不需要它,但在 crontab 条目中需要它以确保 shell 可以看到整个命令。

这样做会将选择合适日期的所有逻辑放在同事首先查看的位置,如果需要,您可以在另一天手动运行脚本。

于 2014-10-17T13:16:33.053 回答
2

有两份工作怎么办

0 0 0 ? * 7#2
0 0 0 ? * 7#4

第一个给

2015-12-12 00:00:00 (-08:00)
2016-01-09 00:00:00 (-08:00)
2016-02-13 00:00:00 (-08:00)
2016-03-12 00:00:00 (-08:00)
2016-04-09 00:00:00 (-07:00)

第二个给出

2015-11-28 00:00:00 (-08:00)
2015-12-26 00:00:00 (-08:00)
2016-01-23 00:00:00 (-08:00)
2016-02-27 00:00:00 (-08:00)
2016-03-26 00:00:00 (-07:00)
于 2015-11-20T00:03:08.953 回答
1

如果你有它可用,你可以使用ncal来获取一个日历,在第一列的旁边有一个日期名称,你可以在其中 grep 一周中的哪一天,以便获取当天所在月份的日期:

    2012 年 8 月
苏 5 12 19 26
钼 6 13 20 27
涂 7 14 21 28
我们 1 8 15 22 29
2 9 16 23 30
周五 3 10 17 24 31
萨 4 11 18 25

如果你用grep表示星期六的“Sa”,你会得到一行包含星期六的月份日期。如果您使用awk解析出特定列(awk '{print($3)}' 用于“第二个”星期六,awk '{print($5)}' 用于第四个星期六)并将其与今天的日期(date + %e),那么你就会知道脚本是否需要运行。

然后,您可以围绕此构建一个脚本,并将其链接到周六运行的 crontab 条目中。因此,当它在星期六运行时,如果日期等于第 2 个或第 4 个星期六,则干净地退出,然后在此脚本之后的 crontab 条目中使用 && 来运行实际作业。但如果是第 1 或第 3 个星期六,则退出 1,然后 && 将不会运行该作业。(你会收到一封 cron 错误电子邮件,说它没有完成或其他)

于 2012-08-13T18:01:40.020 回答
1

上述解决方案效果很好。此外,我遇到了一个更复杂的挑战,我有多组脚本,每组都依赖于另一组。第一组脚本必须在每月的第三个星期日运行。每月第三个星期日之后的星期一的第二组脚本,依此类推。在上述解决方案的基础上,我提出的解决方案如下:

第三个星期日日期 15-21。

第 3 个星期日日期 16-22 之后的星期一。

第 3 个星期日日期 17-23 之后的星期二。

其他日期范围由与第一组脚本(即触发脚本)的天数差异抵消。

于 2014-01-10T19:26:48.280 回答