Crontab 每月的第一周的周五某个点执行一次
问题来了
最近有个需求,让我头大了好一阵子:每个月的第一周的周五早上6点,要执行一次任务。一开始我想,这还不简单?直接写个 crontab 表达式不就得了!
于是我写了个这样的表达式:
|
|
心想,这下应该没问题了吧?结果一测试,发现任务不仅在第一周的周五跑,还在其他时间乱跑!我当时就懵了,这 crontab 是不是有点“脑筋急转弯”啊?
原来是这么回事
我赶紧去查了下 crontab 的官方文档(man 5 crontab),发现了一个关键点:
注意: 命令的执行日期可以通过两个字段指定——每月的某一天和星期几。如果这两个字段都被限制了(即不是
*),那么只要其中一个字段匹配当前时间,命令就会被执行。例如:
130 4 1,15 * 5这个表达式会在每个月的1号和15号,以及每个星期五的早上4:30执行任务。
我当时就明白了,原来 crontab 是“只要满足其中一个条件就执行”,而不是“同时满足两个条件才执行”。这就好比你跟朋友说:“周末或者下雨天我们去吃饭吧!”结果他每天都想去吃饭,因为每天要么是周末,要么会下雨。
解决方案来了
既然 crontab 本身搞不定,那就得靠点“外力”了。我决定用 crontab 加上 shell 脚本来解决这个问题。具体做法是:让 crontab 每天都检查一下,如果是目标时间就执行任务。
于是我写了个这样的表达式:
|
|
这里的关键是 if [ \date ‘+%w’` = “5” ]; then … fi,它会检查今天是不是星期五(%w` 表示星期几,5 表示星期五)。如果是星期五,就执行任务;如果不是,就啥也不干。
总结
经过一番折腾,终于搞定了这个需求。虽然 crontab 本身有点“脑筋急转弯”,但只要稍微动点心思,还是能搞定的。希望这个解决方案对你也有帮助!