正在加载,请稍候…

Cron 语法指南:如何编写 Cron 表达式及实用示例

通过本完整指南掌握 cron 任务语法,涵盖五个字段、特殊字符、命名快捷方式以及 30 多个实际调度示例。

Cron 语法指南:如何编写 Cron 表达式及实用示例

什么是 Cron?

Cron 是 Unix/Linux 系统中基于时间的任务调度器。它可以在指定的时间间隔(从每分钟到每年一次)运行命令或脚本,无需手动触发。

调度由 cron 表达式 定义:一个包含 5 个字段的字符串,描述何时运行。

Cron 语法指南:如何编写 Cron 表达式及实用示例 插图

Cron 表达式结构

┌─────────── 分钟 (0–59)
│ ┌───────── 小时 (0–23)
│ │ ┌─────── 日 (1–31)
│ │ │ ┌───── 月 (1–12 或 JAN–DEC)
│ │ │ │ ┌─── 星期 (0–7,0 和 7 表示星期日,或 SUN–SAT)
│ │ │ │ │
* * * * *  要执行的命令

每个字段可以是:

  • * — 任意值(“每”)
  • 数字 — 特定值
  • a,b — 列表
  • a-b — 范围
  • */n — 每 n 个单位(步长)
  • a-b/n — 带步长的范围

特殊字符说明

字符 示例 含义
* * * * * * 每分钟
, 0 9,17 * * * 在 9:00 和 17:00
- 0 9-17 * * * 从 9 点到 17 点每小时
/ */15 * * * * 每 15 分钟
L 0 0 L * * 月份的最后一天(某些实现)
? 0 0 ? * MON 无特定值(Quartz 调度器)

命名快捷方式

许多 cron 实现支持以下便捷别名:

快捷方式 表达式 含义
@yearly@annually 0 0 1 1 * 每年一次,1 月 1 日午夜
@monthly 0 0 1 * * 每月一次,1 日午夜
@weekly 0 0 * * 0 每周一次,星期日午夜
@daily@midnight 0 0 * * * 每天一次午夜
@hourly 0 * * * * 每小时一次
@reboot 启动时一次

30 多个实用 Cron 表达式示例

每 N 分钟/小时

* * * * *          # 每分钟
*/5 * * * *        # 每 5 分钟
*/10 * * * *       # 每 10 分钟
*/15 * * * *       # 每 15 分钟
*/30 * * * *       # 每 30 分钟
0 * * * *          # 每小时(:00 时)
0 */2 * * *        # 每 2 小时
0 */6 * * *        # 每 6 小时
0 */12 * * *       # 每 12 小时

Cron 语法指南:如何编写 Cron 表达式及实用示例 插图

特定时间

0 0 * * *          # 每天午夜
0 6 * * *          # 每天上午 6:00
30 8 * * *         # 每天上午 8:30
0 9-17 * * *       # 从上午 9 点到下午 5 点每小时
0 9,12,15 * * *    # 在上午 9 点、中午和下午 3 点
0 0 * * 0          # 每个星期日午夜
0 0 * * 1          # 每个星期一午夜
0 0 * * 1-5        # 每个工作日午夜
0 0 * * 6,0        # 每个周末午夜

每月和每年

0 0 1 * *          # 每月第一天午夜
0 0 15 * *         # 每月 15 日午夜
0 0 1,15 * *       # 每月 1 日和 15 日
0 0 1 1 *          # 1 月 1 日(新年)
0 0 1 */3 *        # 每季度第一天
0 0 L * *          # 月份最后一天(支持 L 的 cron)

实际任务示例

# 每天凌晨 2 点备份数据库
0 2 * * * /scripts/backup-db.sh

# 每个星期日凌晨 3 点清理临时文件
0 3 * * 0 find /tmp -mtime +7 -delete

# 每个星期一上午 9 点发送周报
0 9 * * 1 /scripts/send-weekly-report.sh

# 每月 1 日和 15 日凌晨 3 点续订 SSL 证书
0 3 1,15 * * certbot renew --quiet

# 每 30 分钟检查磁盘空间
*/30 * * * * /scripts/check-disk.sh

# 工作时间内每 5 分钟运行 Node.js 脚本
*/5 9-17 * * 1-5 node /app/sync-data.js

# 每晚 11 点重启服务
0 23 * * * systemctl restart myapp

# 每月 1 日凌晨 1 点归档日志
0 1 1 * * gzip /var/log/app/*.log

设置 Crontab

# 编辑当前用户的 crontab
crontab -e

# 列出当前 crontab
crontab -l

# 删除 crontab
crontab -r

# 编辑特定用户的 crontab(以 root 身份)
crontab -u www-data -e

示例 crontab 文件:

# 环境变量
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=admin@example.com

# 任务
0 2 * * * /home/ubuntu/backup.sh >> /var/log/backup.log 2>&1
*/5 * * * * /home/ubuntu/health-check.sh
0 9 * * 1 /home/ubuntu/weekly-report.sh

常见陷阱

Cron 语法指南:如何编写 Cron 表达式及实用示例 插图

1. PATH 问题

Cron 使用最小 PATH 运行。在 shell 中能正常运行的脚本在 cron 中可能因找不到命令而失败。

修复:在脚本中使用完整路径:

# 在 crontab 或脚本顶部:
PATH=/usr/local/bin:/usr/bin:/bin

# 或使用绝对路径
/usr/bin/python3 /home/ubuntu/script.py

2. 缺少输出捕获

除非设置了 MAILTO,否则 cron 默认丢弃 stdout/stderr。

# 将输出重定向到日志文件
0 2 * * * /scripts/backup.sh >> /var/log/backup.log 2>&1

# 抑制所有输出(谨慎使用)
0 2 * * * /scripts/backup.sh > /dev/null 2>&1

3. 任务重叠

如果任务执行时间超过间隔,可能会同时运行多个实例。通过以下方式防止:

*/5 * * * * flock -n /tmp/myjob.lock /scripts/myjob.sh

4. 星期编号

星期 0 和 7 都表示星期日,星期 1 表示星期一。使用特定日期时请仔细检查。

Cron 替代方案

工具 使用场景
systemd timers 现代 Linux,更好的日志记录
Kubernetes CronJob 基于容器的定时任务
AWS EventBridge 云原生调度
GitHub Actions schedule 基于 CI/CD 的自动化
APScheduler (Python) 进程内调度
node-cron Node.js 进程内调度

常见问题

问:cron 的最小间隔是多少? 1 分钟。Cron 不支持小于 1 分钟的间隔。对于频繁任务,请在长时间运行的进程中使用循环。

问:计算机关闭时 cron 会运行吗? 不会。如果系统在计划时间关闭,则该次运行会被跳过。对于错过也必须运行的任务,请使用 anacron

问:为什么我的 cron 任务没有运行? 检查:cron 服务是否运行(systemctl status cron),语法是否正确,脚本中是否使用完整路径,文件权限是否正确,并查看 /var/log/syslog 中的错误。

问:如何在特定时区运行 cron 任务? 在 crontab 中设置 TZ:在任务前添加 TZ=America/New_York。或者使用 systemd timers,它们原生支持时区。

→ 使用 Crontab Generator 可视化生成 cron 表达式。