【发布时间】:2019-06-18 16:15:25
【问题描述】:
我看到this 问题表明CRON 计划的wday 和mday 字段之间的关系是OR 关系。例如,我想在 13 号的每个星期五安排一些事情。
CRON 不是预期的结果
0 0 13 * 5
每个月的所有星期五以及每个月的 13 号都会给我。
有什么方法可以避免这种行为并指定 AND 关系? (似乎提到了使用 AND 关系的旧版本,但我更喜欢使用能够同时执行这两种操作的单一工具)
【问题讨论】:
标签: cron
我看到this 问题表明CRON 计划的wday 和mday 字段之间的关系是OR 关系。例如,我想在 13 号的每个星期五安排一些事情。
CRON 不是预期的结果
0 0 13 * 5
每个月的所有星期五以及每个月的 13 号都会给我。
有什么方法可以避免这种行为并指定 AND 关系? (似乎提到了使用 AND 关系的旧版本,但我更喜欢使用能够同时执行这两种操作的单一工具)
【问题讨论】:
标签: cron
您感兴趣的 cron-entry 是:
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7)
# | | | | |
# * * * * * command to be executed
0 0 13 * * [ $(date "+\%u") = "5" ] && command
这将在每个月的 13 号执行一次 cronjob。它将计算星期几,并测试它是否是星期五(5)。如果是这样,它将执行command。
扩展说明: 如果想要有特殊条件,一般需要自己通过测试来实现条件。下面是一般结构:
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7)
# | | | | |
# * * * * * command to be executed
0 0 13 * * /path/to/testcmd && command
testcmd 命令通常在测试成功时返回退出代码 0,如果测试失败则返回 1。如果testcmd 成功,则执行command。以下帖子中有一些使用类似技巧的示例:
您要执行的测试写在/bin/sh 中:
[ $(date "+%u") = 5 ]
其中使用了test 命令(参见man test)。这是 POSIX 兼容的,并且适用于您的 cron 可能运行的任何 shell(sh、bash、dash、ksh、zsh)。命令date "+%u" 返回从 1 到 7 的工作日(星期日是 7)。请参阅man date 了解更多信息。
所以你的 cronjob 看起来像:
0 0 13 * * [ $(date "+\%u") = 5 ] && command
请注意,我们必须转义
命令中的
%字符,除非使用反斜杠 (\) 转义,否则将更改为换行符,并且第一个%之后的所有数据将作为标准输入发送到命令。来源:
man 5 crontab
【讨论】:
我想,您不必指定 wday (Friday=5),而只需指定 13 日是星期五的月份;所以,对于 2019 年:
0 0 13 9,12 * : do stuff, but avoid black cats
或者,永远更优雅,创建一个小脚本:
$> cat /home/me/bin/test_friday_13
#!/bin/bash
if [ "$(date +'%A %d')" != "Friday 13" ]
then
exit 1
else
: do stuff, but avoid black cats
exit 0
fi
并创建 crontab 条目:
0 0 13 * * /home/me/bin/test_friday_13
脚本方法的另一个好处是您可以从命令行运行它。 (注意:不要忘记更改脚本中的工作日名称以反映您的环境。)
【讨论】:
9,12 方法有风险。 crontab 很可能不会在 2020 年 3 月之前正确更新(2019 年之后的下个月,即 13 号星期五)。包装脚本很好,是 cron 限制的一个非常常见的解决方法。
很遗憾,CRON 不能按您想要的方式工作
您可以在下面的 url 上看到所有可用的选项
https://www.freeformatter.com/cron-expression-generator-quartz.html
所以你可以做的是在每个月的 13 号执行一次 cron,但不要让命令在其 Friday 时运行
0 0 0 13 * ? * mybatchjob.sh
mybatchjob.sh
if [ `date +'%A'` = "Friday" ]; then
echo "Yep its Friday";
else
echo "Not Friday";
fi
这将确保预期的程序仅在星期五和 13 日运行
【讨论】:
locale。 $ LC_ALL=is_IS.utf8 date '+%A' 周五返回 föstudagur。