You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何编写排除每月最后一个周一的Cron表达式

如何编写排除每月最后一个周一的Cron表达式

嘿,我来帮你搞定这个调度需求!看起来你想要让任务在每月的每个周一凌晨00:05自动运行,但得跳过当月的最后一个周一对吧?我分两种场景给你具体方案:


一、使用支持扩展语法的Cron(比如Quartz调度框架)

如果你的调度系统支持Quartz风格的扩展Cron语法,直接用表达式就能实现需求:

0 5 0 ? * MON#1-MON#4

或者更灵活的方式:先设置基础触发规则为所有周一00:05,再配合调度器的排除规则,跳过MON#L(代表当月最后一个周一)的触发。

语法说明:

  • 0 5 0:对应凌晨00:05(Quartz的Cron顺序是秒 分 时,所以秒设为0,分是5,时是0)
  • ?:表示不指定具体日期(因为我们用周几来触发任务)
  • MON#1-MON#4:明确指定运行每个月的第1到第4个周一(一个月最多有5个周一,这样就自动排除了最后一个)

二、标准Linux Cron(无扩展语法)

标准Linux Cron本身没有直接的“排除最后一个周一”的语法,我们可以结合Shell脚本做日期判断,再通过Cron调用脚本:

步骤1:编写判断脚本(比如命名为run_job.sh

#!/bin/bash
# 判断当天是否为当月最后一个周一
next_monday=$(date -d "$(date +%Y-%m-01) +$(( ( $(date +%u) % 7 ) + 7 )) days" +%Y-%m-%d)
current_month=$(date +%m)
next_month=$(date -d "$next_monday" +%m)

if [ "$current_month" -eq "$next_month" ]; then
    # 下一个周一仍在当前月,说明今天不是最后一个周一,执行任务
    echo "[$(date +%Y-%m-%d %H:%M:%S)] 开始执行任务..."
    # 在这里写入你的具体任务命令
else
    # 下一个周一进入下个月,说明今天是最后一个周一,跳过任务
    echo "[$(date +%Y-%m-%d %H:%M:%S)] 跳过任务:今日是当月最后一个周一"
fi

步骤2:设置Cron表达式

让Cron在每周一凌晨00:05调用这个脚本,同时记录日志:

5 0 * * 1 /path/to/run_job.sh >> /var/log/monthly_job.log 2>&1

脚本逻辑验证

拿你提到的例子来说:某个月的周一分别是3号、10号、17号、24号

  • 3号、10号、17号的下一个周一都在当月,脚本会正常执行任务
  • 24号的下一个周一已经是下个月的1号,脚本会自动跳过这次运行,完全符合你的预期!

备注:内容来源于stack exchange,提问作者Brijesh Cg Cg

火山引擎 最新活动