核心答案:cron 表达式 = 分 时 日 月 周 五段,空格分隔。每天凌晨 3 点:0 3 * * *;每 5 分钟:*/5 * * * *;工作日 9:30:30 9 * * 1-5。记住段序口诀「分-时-日-月-周」,90% 的错误都是段序写反。

五段语法结构

```

┌ 分(0–59)

│ ┌ 时(0–23)

│ │ ┌ 日(1–31)

│ │ │ ┌ 月(1–12)

│ │ │ │ ┌ 周(0–6,0 和 7 都是周日)

* * * * *

```

四个特殊符号

符号含义示例
*任意值* * * * * 每分钟
*/n每 n 步进*/10 * * * * 每 10 分钟
a-b区间0 9-18 * * * 9 到 18 点整点
a,b,c枚举0 9,12,18 * * * 三个时刻

组合示例:*/15 9-18 * * 1-5 = 工作日 9–18 点每 15 分钟。

20 个常用表达式速查

需求表达式
每分钟* * * * *
每 5 分钟*/5 * * * *
每小时整点0 * * * *
每天零点0 0 * * *
每天凌晨 3 点0 3 * * *
每天 9:3030 9 * * *
每小时第 15/45 分15,45 * * * *
工作日 9 点0 9 * * 1-5
周末 10 点0 10 * * 6,0
每周一 8 点0 8 * * 1
每月 1 号零点0 0 1 * *
每月最后一天零点(2 月特殊)0 0 28-31 * *(见踩坑)
每季度首日 1 点0 1 1 1,4,7,10 *
每年 1 月 1 日0 0 1 1 *
工作日每 10 分钟(9–18 点)*/10 9-18 * * 1-5
每隔 2 小时0 */2 * * *
每天 6:00 和 18:000 6,18 * * *
周日到周四 23 点0 23 * * 0-4
每月 15 号中午0 12 15 * *
开机执行一次@reboot(非五段扩展)

实例:三条真实需求

例一(数据库备份):每天凌晨 2:30 备份,避开业务高峰 → 30 2 * * * /scripts/backup.sh

例二(日志清理):每周日凌晨 4 点清理 7 天前日志 → 0 4 * * 0 find /logs -mtime +7 -delete

例三(接口巡检):工作时间每 10 分钟探测,非工作时间不打扰 → */10 8-19 * * 1-5 curl -s https://api/health

crontab 使用要点

  • crontab -e 编辑、crontab -l 查看、crontab -r 清空(危险)
  • 命令用绝对路径:cron 的 PATH 极简(/usr/bin:/bin),脚本内 cd 到工作目录
  • 输出重定向:>> /var/log/job.log 2>&1,否则报错全丢
  • 环境变量在 crontab 文件顶部显式声明
  • 改完立即生效,无需重启服务

六个高频踩坑

  1. 段序写反:想写「3 点」写成 3 0 * * *(这是每月 3 号零点)——正确 0 3 * * *
  2. 百分号转义:命令中的 % 必须写成 \%,否则被当作换行
  3. 相对路径:脚本里 ./data 找不到——cron 工作目录不是脚本所在目录
  4. 「每月最后一天」:cron 不支持 L,用 0 0 28-31 * * 配合脚本内判断 [ $(date -d tomorrow +\%d) -eq 1 ]
  5. 「每 90 分钟」:*/90 不合法(分钟段 >59),拆成 0 0,3,6,9,12,15,18,21 * * * 或写两行
  6. 时区:cron 按服务器系统时区执行,跨国服务器先 timedatectl 确认

常见误区

  • 「日和周同时写是且的关系」:标准 cron 中「日」和「周」都非 * 时是的关系(任一满足即触发),0 9 1 * 1 是每月 1 号每周一都执行。
  • 「改完 crontab 要重启」:不需要,保存即生效;不生效先查日志 grep CRON /var/log/syslog。
  • 「秒级调度」:标准 cron 最小粒度是分钟,秒级任务用 systemd timer 或程序内循环。
  • 「周末写 1-5」:1-5 是周一到周五(工作日),周末是 6,0 或 6,7。

用[cron 表达式计算器](/c/dev/cron)输入表达式立即看到未来 10 次执行时间,[时间戳转换器](/c/dev/timestamp)处理日志时间。