Cron 表达式解释器,免费

粘贴 cron 表达式,完全理解它的含义。

常见示例

如何读懂 cron 表达式

标准 cron 表达式包含 5 个字段,以空格分隔:

分钟 小时 日 月 星期

* · 任意值   */n · 每 n 个单位   1,5 · 在 1 和 5   1-5 · 从 1 到 5 范围

取值范围:分钟(0–59)、小时(0–23)、日(1–31)、月(1–12)、星期(0–6,0 = 周日)

工作原理

  1. 输入 cron 表达式:粘贴 5 或 6 字段的 cron 字符串,例如 0 9 * * 1-5
  2. 阅读通俗解释:工具立即显示任务将在何时运行的可读描述。
  3. 查看下一次运行时间:从当前日期时间起显示接下来 5 到 10 次计划运行。
  4. 校验:无效表达式会被高亮并显示精确的错误信息,说明具体问题。

整整半个世纪、每分钟一次的滴答

cron 是世界上大多数服务器至今仍每天连续使用的最古老的调度器。它在历史档案中的首次出现是1975 年 5 月,那时一个早期版本作为 Research Unix 分支的一部分从 AT&T Bell Laboratories 流出。这个名字是对希腊时间之神 Chronos 的致敬,而它的设计也以一种奇怪的优雅老去:1970 年代中期 Bell Labs 工程师在 /usr/lib/crontab 里敲下的那五个用空白分隔的字段,今天仍然驱动着 Kubernetes CronJob、GitHub Actions 的调度,以及此刻法兰克福某个虚拟专用服务器上的夜间数据库备份。1975 年的实现极为简陋,只有一份 crontab,由 root 拥有,服务整台机器。要是某个用户想要一个周期性任务,他得请管理员手工添加一行。cron 在 1979 年发布的 Version 7 Unix 中走向更广阔的世界。1979 年末,普渡大学的 Robert Brown 和 Keith Williamson 把 cron 扩展到支持多用户,引入了按用户的 crontab -e 工作流。决定性的重写是 Paul Vixie 于 1987 年 5 月 6 日发布的 vixie-cron 1.0;vixie-cron 把那些特殊字符正式化下来,并引入了 @reboot@hourly@daily@weekly@monthly@yearly 这些快捷写法。Vixie 3.0(1993 年 12 月 27 日)加入了步长(/)的写法,并以略有补丁的形式进入了那个时代几乎所有的 Linux 发行版和 BSD。POSIX 在 1992 年才追上(IEEE Std 1003.2-1992)。今天 cron 的每一处奇怪之处(错位的星期天编号、日字段“并集 vs 交集”的 bug)都是这段演化留下的疤痕;没有哪一处是一次性设计出来的。

五字段表达式的剖析

一条标准的 cron 表达式由五个用空白分隔的字段构成。从左到右,它们问的是:哪一分钟、属于哪一小时、属于一个月的哪一天、属于哪一个月、属于一周的哪一天?具体取值范围在 POSIX cron 中是不容讨价还价的:分钟 0-59,小时 0-23,月份中的日 1-31,月份 1-12,周内的日 0-7,其中 0 和 7 都表示星期天。每个字段都接受五个可以自由组合的运算符:* 表示任何合法值;, 分隔一组离散值(0,15,30,45 * * * * 表示每小时的整点、过一刻、过半、再过一刻钟运行);- 表示一个闭区间(小时字段中的 9-17 表示 9、10、11、12、13、14、15、16、17);/ 表示步长(分钟字段中的 */15 表示从 0 开始每隔十五分钟,即 0、15、30、45)。月份和星期也可以写成三字母缩写:JAN-DECSUN-SAT。一个完整的例子:*/15 9-17 * * 1-5 解读为每月每一天、每年每一个月,从星期一到星期五,9 点到 17 点(含 17 点整)这段时间内每十五分钟一次,也就是“工作日上班时间内每一刻钟”。

“月份中的日 / 周内的日”陷阱

cron 中后果最严重的怪癖(三十五年来在生产环境里一次次造成停机、错过备份、悄悄搞错账单运行的那一个)是当“月份中的日”和“周内的日”两个字段同时被限制时它们的组合方式。POSIX 在这里的措辞罕见地精确:“如果 ‘月份中的日’(字段 3)和 ‘周内的日’(字段 5)都受到限制(不包含 ‘*’),那么二者中只要有一个匹配当前日,就算匹配。”换句话说,当两个字段都不是通配符时,cron 取的是它们的并集(任何一天,只要满足其中任意一个限制,任务就会运行。这与大多数用户的直觉正相反。把 0 0 13 * 5 念出来)“13 号那天的午夜,且是星期五”,自然听起来像交集:只在“黑色星期五”运行。但在 vixie-cron 及其后继者里,它实际上意味着“每月 13 号以及每个星期五”,一个月大约触发九次。更糟的是,vixie-cron 是通过查看每个日字段的第一个字符来决定是用并集还是交集的。Paul Vixie 本人也承认这是个bug,但拒绝修复,理由是修复它会违反“最少惊讶原则”,已经有数百万 crontab 是基于这个既有行为是有意为之的假设写出来的。于是这个 bug 现在反而是一项特性,永生不灭、在自我繁殖。务实的心理模型是:如果你发现自己同时限制了月份中的日和周内的日,并且真的想要交集(例如“每月的第二个星期二”),就在支持它的实现里使用 # 运算符(Quartz、带扩展的 cronie):0 12 ? * 2#2。在纯粹的 POSIX cron 里,交集真的没法在一条表达式中表达出来,你只能在 cron 调用的脚本内部做过滤。

几个快捷宏

这些快捷写法不是 POSIX 的内容。严格只允许 POSIX 的环境会拒绝 @daily;但实际上读者可能遇到的每一个 cron 实现(vixie-cron、cronie、fcron、ISC cron、容器镜像)都支持它们。

各种方言,标准 vs Quartz vs AWS vs K8s vs systemd

“cron 表达式”如今已经是一小群相互不兼容的方言。标准 5 字段 cron(POSIX、vixie-cron、cronie):分钟 小时 月份中的日 月份 周内的日,通用的最小公倍数。Quartz Scheduler(6 或 7 字段,Java 生态):秒 分 时 月份中的日 月份 周内的日 [年];引入了 ?L(last,最后)、W(weekday,最近的工作日)、#(每月第 n 个星期几)。Spring 的 @Scheduled 和 Spring Boot 都使用 Quartz。Kubernetes CronJob 用的是标准 5 字段 cron,并配有一个独立的 spec.timeZone 字段,该字段在 K8s 1.27 中正式 GA(CronJob 资源本身在 1.21 也即 2021 年4 月已 GA);时区的格式是 IANA tz 数据库(Europe/BerlinAmerica/New_York)。GitHub Actions 的 cron schedule 使用 5 字段 POSIX cron,并以 UTC 运行。AWS EventBridge 的 cron 使用 6 字段(分钟 小时 月份中的日 月份 周内的日 年),要求月份中的日和周内的日中至少有一个写成 ?(不能同时限制两者),并使用 1-7 编号、SUN=1,意味着 EventBridge 里的 0 12 ? * 2 * 会在星期一中午运行,而不是星期二。systemd 定时器用的是完全不同的语法(OnCalendar=*-*-* 02:00:00),并在现代 Linux 上正逐步取代 cron 用作系统级调度,尽管二者在每一个主流发行版里都并存。Cloud Scheduler(Google Cloud)使用标准 5 字段 cron,并显式配置时区。在不同平台之间互译表达式时需要格外小心:从 EventBridge 复制粘贴过来的 schedule,在 vixie-cron 里会因为周内的日编号不同而在错误的星期几运行。

值得记住的常用模式

常见的坑

时区。cron 默认使用系统的本地时间,这在默认 UTC 的云机器上很容易让人意外。UTC 服务器上一个上午 9 点的 cron 任务会在美东时间凌晨 4 点触发。现代调度器(Kubernetes 1.27+、AWS EventBridge、Cloud Scheduler)加入了显式的时区字段;经典 cron 没有。“*/N 总是从 0 开始”这条规则。*/15 是 0、15、30、45(不是 5、20、35、50。要从非零的偏移开始,你得列举(5,20,35,50)或者使用只在 Quartz 里才有的 5/15 写法。60 分钟的“堆积陷阱”。一个执行时间超过其调度间隔的任务可能会堆起来)三份 30 分钟的备份每 15 分钟触发一次的话就会重叠。标准的缓解办法是 flock(1)* * * * * /usr/bin/flock -n /tmp/myjob.lock /path/to/myjob 保证同时只跑一份;-n 标志让锁的获取变成非阻塞,所以后续的调用会安静地退出,而不是排起队。夏令时异常。一个排在 02:30 的 cron 任务,在时钟回拨的那天会触发两次,在时钟前拨的那天则完全不会触发。cron 并不存在“按墙上时钟、考虑夏令时来调度”这种概念;如果你的调度必须避开夏令时切换,请把它锚定到一个不受影响的小时(在大多数时区是凌晨 3 点或更晚),或者使用一个真正理解时区语义的调度器。PATH 被剥光。cron 任务运行时使用的是一个最小化的 PATH(/usr/bin:/bin)以及几乎为空的环境;那些在你交互式 shell 里能跑的脚本,到了 cron 里可能因为 nodepython3aws 不在继承的 PATH 上而失败。要么在 crontab 顶部设置 PATH=,要么在 cron 命令里使用绝对路径。邮件爆仓。默认情况下 cron 会把每个任务的输出邮件发到用户的本地信箱;在没配置邮件的服务器上,这会悄悄把 /var/spool/mail 塞满,直到磁盘耗尽。要么把输出重定向 (>/dev/null 2>&1),要么在 crontab 顶部设置 MAILTO="",要么真的去配置一个邮件转发器。

现代替代品,什么时候该用别的

cron 在单台机器上的简单周期任务上很出色。它在以下方面表现糟糕:分布式调度(同一个任务在整个机器群里只触发一次,而不是每台机器触发一次)、事件驱动触发(在队列收到消息时运行,而不是按时钟)、监控(如果任务以非零退出码失败,cron 会沉默地失败,除非你配置了邮件转发)、重试(没有内建机制,失败的任务会在下一个周期再跑一遍并累积状态)以及依赖(任务 B 仅在任务 A 成功完成后再运行)。对于这些场景,现代答案是其中之一:Kubernetes CronJob(具备集群感知的调度,带重试和并行度策略)、AWS EventBridge + Lambda 或 Step Functions(事件驱动,自带可观测性)、Apache AirflowPrefect(基于 DAG、显式依赖的工作流编排)、Temporal(持久化的工作流执行)、healthchecks.io(一种“死人开关”,当一个 cron 任务没有按时运行时通知你)。在 2026 年,对单机周期任务来说,普通的 cron 仍然是正确答案;其他情况,为这些替代品多花一点配置成本是值得的。

常见问题

cron 表达式中的 * 是什么意思?

cron 字段里的星号(*)表示“任何合法值”,每一分钟、每一小时、每一天、每一个月、一周里的每一天。* * * * * 每天每分钟都会运行。星号在“月份中的日”和“周内的日”这两个字段里也很特殊,因为有“并集 vs 交集”的陷阱:当两个日字段中有一个以 * 开头时,vixie-cron 走的是“交集”模式;当两个都没有星号时,它走的是“并集”模式,在两边限制的并集上运行。

我怎么让 cron 任务每 15 分钟跑一次?

用步长写法:*/15 * * * * 每 15 分钟跑一次(在 xx:00、xx:15、xx:30 和 xx:45 触发。注意 */N 总是从 0 开始;你不能用 */15 来表达“从第 5 分钟开始每 15 分钟一次”)那种情况你要写 5,20,35,50 * * * *。Quartz 方言的 cron 支持 5/15 作为一个非标准的替代写法。

cron 和 at 有什么区别?

cron 按重复的时间表运行任务(每分钟、每天、每周)。at 命令则把一次性任务排到将来某个特定时间执行,at 14:30 tomorrow 把一个任务排进队列,只在那一个时刻运行。周期性的事用 cron,一次性的未来执行用 at。两者都源自同一条 Bell Labs / vixie-cron 血脉,并且在大多数系统上最终被合并到了同一个守护进程里。

为什么我的 cron 任务和我预期的不一致?

按出现频率粗略排序的五个最常见原因:(1) 月份中的日 vs 周内的日弄混(当两者同时被限制时,cron 走的是它们的并集,而不是交集。(2) 时区)cron 默认使用服务器的本地时间,云机器上经常是 UTC。(3) PATH 问题(你交互式 shell 的 PATH 不会被继承,所以在命令行里能跑的命令到了 cron 里可能会失败。(4) */N 总是从 0 开始的陷阱。(5) 输出完全没有被捕获)如果你没有设置邮件,也没有把输出重定向到日志文件,失败的任务会无声无息地消失。这个解释器中的“接下来 10 次调度”面板,是部署前确认你的表达式到底意味着什么的最便宜的办法。

这个工具支持非标准的 cron 格式吗?

它能处理标准 5 字段 POSIX/vixie-cron、带秒的 6 字段 Quartz/Spring 变体,以及那些特殊字符串:@hourly@daily@weekly@monthly@yearly@reboot。它不处理完整的 Quartz 扩展(LW#),也不处理 AWS EventBridge 那种从 1 开始的星期编号,那些情况,请在部署前使用平台自家的校验器。

我的 cron 表达式会被发送到任何地方吗?

不会。解析与解释完全在你的浏览器中通过 JavaScript 运行。粘贴的表达式永远不会跨越网络,你可以在点击“解释”时打开开发者工具的网络标签页查看。对生产 CI 配置、基础设施代码以及任何作息表本身可能涉及敏感信息的运维 runbook 中的 cron 表达式(例如暗示停机窗口的夜间数据库导出 schedule)都安全。

相关工具