【问题标题】:Run every 2nd and 4th Saturday of the month每个月的第 2 和第 4 个星期六运行
【发布时间】:2012-07-27 07:36:05
【问题描述】:

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

【问题讨论】:

    标签: cron crontab


    【解决方案1】:

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

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

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

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

    【讨论】:

      【解决方案2】:

      每月的第二个星期六是从 8th 到 14th 的日期中的一个(也是唯一一个)。同样,第四个星期六是一个,介于 22nd 和 28th 之间。

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

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

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

      cron 在年中的分钟、小时和月份字段与当前时间匹配时,并且当两个 天字段中的至少一个(月中的日或日)时,将执行命令of week) 匹配当前时间。

      可以通过两个字段指定命令执行的日期 - 月中的日期和星期几。如果两个字段都受到限制(即不是 *),则当任一字段与当前时间匹配时,将运行该命令。例如,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
      

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

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

      0 1 8-14,22-28 * * [ `date +\%u` = 6 ] && /path/to/myscript
      

      【讨论】:

      • 只是想知道, * * * * 6/2 会做什么?
      • @chochim,据我所知,跳过仅对范围有用(例如 1-5/2 表示 1、3、5)。如果将它们应用于单个值,则与仅使用单个值相同。您几乎在那里,您可以将日期用作 1-31/14,但这会给您 1,15,因此不能保证它是星期六。跨度>
      • 0 1 1-7,15-21 6 /path/to/myscript 应该是 0 1 1-7,15-21 * 6 /path/to/myscript。缺少月份条目。否则有用的答案!
      【解决方案3】:

      如果你有它,你可以使用 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 错误电子邮件,说它没有完成或其他什么)

      【讨论】:

        【解决方案4】:

        有两份工作怎么样

        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)
        

        【讨论】:

        • 这个不能和0 0 0 ? * 7#2,7#4合并吗?
        【解决方案5】:

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

        第三个星期日 15-21 日。

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

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

        其他日期范围与第一组脚本(即触发脚本)相差天数。

        【讨论】:

        • 在 cron 中配置这些日期参数时,通过测试轮次提醒我,(月份的日期,月份)和(星期几)在“或”逻辑上运行。因此,请考虑以下示例:07 17 15-21 * 2 /home/user/scripts/execute_this.ksh 这将在一个月中的一天(包括 15-21 之间)或任何星期二执行。因此,最好将星期几保留为“*”,特别是因为脚本建议的条件在星期几条件下运行。
        猜你喜欢
        • 2014-10-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-29
        相关资源
        最近更新 更多