crontab 定时任务实战:五字段语法、常用表达式与排查
从五字段语法讲到 crontab -e 编辑、常用表达式速查、日志排查与按需求生成,配真实例子(每天凌晨 2 点),帮你把 Linux 定时任务一次写对。
crontab 定时任务实战:五字段语法、常用表达式与排查
我维护过一台跑了三年的老服务器,crontab 里挤着十几行任务,大半没人记得当初为什么这么写。最痛的一次,是一条本该「每个工作日凌晨备份」的任务,连续两周只在周一和周五跑,等到要恢复数据时才发现备份缺了一大截。问题就出在一个逗号。所以这篇我想把 cron 最容易踩的地方讲清楚:字段怎么读、表达式怎么记、写完怎么验、出问题怎么查。
五字段语法:先把顺序刻进脑子
经典 POSIX cron 一行就是五个字段加一条命令,顺序固定为:分钟、小时、日(几号)、月、周(星期几)。
分 时 日 月 周 命令
0 2 * * * /opt/backup.sh
逐个拆开看:
- 分钟:0–59
- 小时:0–23
- 日(day-of-month):1–31
- 月:1–12
- 周(day-of-week):0–6,0 是周日,多数实现里 7 也表示周日
每个字段里能写的符号也就四种:* 表示「每个」,, 列举具体值(如 1,15),- 表示范围(如 9-17),*/N 表示步长(如 */15)。上面那行 0 2 * * * 读出来就是:每天 02:00 跑一次备份。这是我最常用的「每天凌晨 2 点」模板,半夜负载低,跑重活不打扰白天的请求。
记不住顺序时,别凭记忆硬写。我现在习惯先用 Crontab 助手 点选生成,五个面板分别对应五个字段,点一下就出表达式,下面还附一句大白话和按本地时区算出的下 5 次触发时间,写错字段在面板里一眼就能看出来。
常用表达式速查
下面这几条覆盖了我日常八成的场景,可以直接抄:
*/15 * * * *:每 15 分钟一次0 * * * *:每小时整点0 2 * * *:每天凌晨 2 点0 9 * * 1-5:工作日每天上午 9 点*/15 9-17 * * 1-5:工作日 9 到 17 点,每 15 分钟一次0 6 1 * *:每月 1 号早上 6 点
有两个坑必须单独点名。第一,「每个工作日」要写 1-5(范围),不是 1,5(只有周一和周五)。第二,*/5 这种步长是从字段起点开始数的,不跨天滚动:小时字段里 */5 给出 0、5、10、15、20,然后到 0 点重置,20:00 到次日 00:00 只隔 4 小时。想要全天候严格每 5 小时一次,单个 cron 字段表达不了,得把小时列死成 0,5,10,15,20 接受这个断点,或者改用 systemd timer。
crontab -e 编辑:别直接动文件
改用户级定时任务,命令是 crontab -e,它会打开当前用户的 crontab 临时副本,保存退出时才校验并装载。几条习惯:
crontab -l先列出现有内容,改之前心里有数crontab -e编辑,每行一个任务,#开头是注释- 给每条任务上面加一行注释写清「干什么、谁负责」,三个月后的你会感谢现在的你
不要直接去手改 /etc/crontab 或 /var/spool/cron 下的文件,那样绕过了 cron 的加载机制,容易出现你以为生效、其实没装载的尴尬。系统级任务(带运行用户字段)才放 /etc/crontab 和 /etc/cron.d/。
日志与排查:任务不跑先看这三处
「定时任务没跑」是运维最常见的报障之一,按这个顺序查基本能定位:
- 看日志。Debian/Ubuntu 一般在
/var/log/syslog,RHEL 系在/var/log/cron,过滤一下:grep CRON /var/log/syslog。能看到 cron 有没有在到点时尝试启动这条任务。 - 看 PATH 和环境变量。cron 跑任务时的环境极简,你登录 shell 里能用的命令在 cron 里可能找不到。解决办法是命令写绝对路径(
/usr/bin/python3而不是python3),或在脚本开头source一份环境。 - 看输出去哪了。cron 会把任务的 stdout/stderr 邮件给用户,很多机器没配邮件就静默丢弃了。我的习惯是显式重定向:
0 2 * * * /opt/backup.sh >> /var/log/backup.log 2>&1,错误信息有据可查。
还有一类容易忽略的情况:笔记本或会休眠的机器,到点时如果在睡,经典 cron 错过就不补跑。需要补跑就用 systemd timer 加 Persistent=true,唤醒后会把错过的那次补上。
按需求生成:先想清楚再写
写 cron 之前,先把需求翻译成「多久一次、几点、哪些天」三件事,再对照五个字段填。举个真实的例子:财务要每月 1 号早上 6 点出账单,需求很清楚,对应表达式就是 0 6 1 * *。但这里藏着时区陷阱:如果服务器跑 UTC 而你在 UTC+8,实际触发会落在你眼里的 14:00。处理涉及时间的任务时,我会顺手用 时间戳转换器 把 UTC 和本地时间对一遍,确认没差出 8 小时,免得第一张账单错了才发现。
把这套流程走顺之后,cron 其实没那么吓人:五个字段读懂、常用表达式记牢、写完用工具验一遍下次运行时间、上线后留好日志。最容易出事的从来不是复杂语法,而是一个写错的逗号没人发现。
Made by Toolora · Updated 2026-06-13