日期与时间

如何读写 cron 表达式:五个字段与常用示例

每天凌晨 2 点备份、工作日上午 9 点发送报告、每十分钟检查一次状态——这里汇总了用 cron 设置定时任务所需的一切。

五个字段

标准 Unix cron 表达式由五个以空格分隔的字段组成:分钟(0–59)、小时(0–23)、日(1–31)、月(1–12)和星期(0–7,0 和 7 都表示星期日)。当所有字段都匹配时任务就会运行。

例如 0 2 * * * 表示第 0 分、2 点、每天、每月、星期不限——即每天凌晨 2:00。星号表示“任意值”。

┌───── 分钟 (0-59)
│ ┌─── 小时 (0-23)
│ │ ┌─ 日 (1-31)
│ │ │ ┌ 月 (1-12)
│ │ │ │ ┌ 星期 (0-7, 星期日=0 或 7)
│ │ │ │ │
0 2 * * *

四个特殊字符

组合这四个字符就能覆盖大多数调度需求。有些系统还接受 MON、JAN 这样的名称。

  • *(任意):小时字段中的 * 表示每小时。
  • ,(列表):1,15 表示每月 1 日和 15 日。
  • -(范围):星期字段中的 1-5 表示周一到周五。
  • /(步长):分钟字段中的 */10 表示 0、10、20……即每十分钟。也可以指定起点,如 5-59/15。

常用示例

写好表达式后,推算接下来几次的运行时间,确认它符合预期。注意步长是从 0 开始计算的,而不是从任务启动时开始:分钟字段中的 */45 会在每小时的 :00 和 :45 运行,而不是每隔 45 分钟。

*/5 * * * *      每 5 分钟
0 * * * *        每小时整点
30 9 * * 1-5     工作日 09:30
0 0 1 * *        每月 1 日零点
0 18 * * 5       每周五 18:00
0 3 * * 0        每周日 03:00
0 9,18 * * *     每天 09:00 和 18:00
0 0 1 1 *        1 月 1 日零点

常见陷阱

最著名的陷阱是同时设置“日”和“星期”。0 0 13 * 5 看起来像“13 号星期五”,但在标准 cron 中,当两个字段都不是 * 时,它们按 OR 组合:任务会在每月 13 日以及每个星期五运行。

第二个陷阱是“每月最后一天”。标准的五字段 cron 没有表示它的符号;常见的变通办法是在 28–31 日运行,并让脚本检查明天是否为 1 日。Quartz 等调度器支持 L,但它们使用含秒的六或七字段格式,与标准 cron 不兼容。

cron 使用哪个时区?

cron 遵循服务器的系统时区。大多数云服务器运行在 UTC,所以本想在北京时间上午 9 点发出的报告,可能在北京时间下午 5 点才发出。北京时间上午 9 点是 UTC 凌晨 1 点,因此在 UTC 服务器上应写成 0 1 * * *。

GitHub Actions 和 Kubernetes CronJob 默认也是 UTC。如果调度与实行夏令时的地区相关,要预期当地运行时间每年会有两次偏移一小时。

运维技巧

在 AIBIZAP cron 生成器中选择“每天”或“每周”即可自动生成表达式,无需记住语法也能把调度设置正确。

  • 把繁重任务分散到 :07 或 :23 这样的分钟,而不是全部在 :00 启动。
  • 如果一次运行可能在下一次开始前还没结束,加锁防止重叠。
  • cron 的环境变量和 PATH 与交互式 shell 不同,脚本中请使用绝对路径。
  • 记录每次运行的输出日志,确保失败不会被忽视。

用这些工具试一试

更多指南

全部指南