crontab原生不支持任意起止区间的连续时间覆盖,仅能表达离散时刻或规则步长;需用高频cron触发+脚本内时间校验实现“2:30至5:45每15分钟”等逻辑,辅以跨日处理、加锁、日志和中断机制保障生产可靠性。

crontab 本身不支持“短横线跨越非标准周期”的语法,比如 0-3 在小时字段中确实表示 0、1、2、3 点,但若你想表达“凌晨 2:30 到清晨 5:45 之间每 15 分钟执行一次”,crontab 原生无法直接实现——它只支持离散时间点或规则步长,不支持任意起止区间的连续覆盖。
理解 crontab 时间字段的边界与限制
crontab 的五段时间字段(分、时、日、月、周)均基于固定日历/时钟刻度设计,所有范围(a-b)都必须落在该字段合法值域内,且被解释为“包含 a 和 b 之间所有整数取值”。例如:
-
30 2-5 * * *表示每天 2:30、3:30、4:30、5:30 各执行一次 —— 它不是“从 2:30 持续到 5:30”,而是四个离散时刻; -
*/15 2-5 * * *表示每天 2:00/2:15/2:30/2:45/3:00/…/5:45,共 16 次 —— 仍属离散枚举,无法表达“2:30 开始、5:45 结束”这种偏移起点的区间。
用包装脚本 + 固定频次 cron 实现“逻辑区间控制”
真正灵活的“凌晨 2:30 至清晨 5:45 每 15 分钟执行”需借助 shell 脚本判断当前时间是否落在目标窗口内。推荐做法:
- 在 crontab 中设置高频触发(如每 5 或 10 分钟),覆盖整个潜在时段(例如
*/10 2-5 * * *); - 实际执行的脚本开头加入时间校验逻辑,用
date +%-H:%-M获取当前时分,转为分钟数(如2:30 → 150,5:45 → 345),再判断是否 ∈ [150, 345]; - 仅当满足条件才运行维护任务,否则
exit 0快速退出。
这样既保持 cron 的简洁性,又赋予脚本层完整的时序逻辑表达能力。
避免跨日歧义:明确使用 24 小时制与 date -d
若维护窗口可能跨零点(如“23:30 至次日 04:15”),单纯用 HOUR 字段无法描述。此时应:
- 将 crontab 触发范围设宽(如
*/10 0-4,23 * * *),覆盖前后两段; - 脚本中统一用
date -d "now" +%-H:%-M获取绝对时间,或更稳妥地用date --date="now" +%s转为 Unix 时间戳,再做数值比较; - 可预计算窗口起止的时间戳(如
start_ts=$(date -d "today 23:30" +%s 2>/dev/null)),提升可读性与复用性。
生产环境建议:加锁 + 日志 + 可中断设计
特种维护流常涉及敏感操作,仅靠时间控制不够:
- 用
flock -n /tmp/maint.lock -c '...'防止并发重叠; - 每次执行记录带毫秒级时间戳的日志(
date '+%F %T.%3N'),便于事后对齐监控; - 脚本开头检查
/tmp/maint.stop文件是否存在,支持人工快速中止后续轮次。











