《Crontab 定时任务入门:从语法到实战一次讲清》
Crontab 定时任务入门:从语法到实战一次讲清
定时任务是服务器运维里最常用的自动化手段:每天凌晨备份数据库、每周清理一次日志、每隔一小时同步一次文件,这些重复劳动交给 crontab,一次配置、长期生效。本文从零讲清 crontab 的语法、常见写法和排坑要点。
一、crontab 是什么
crontab 是 Linux 系统自带的定时任务工具,由 cron 守护进程驱动。系统每分钟检查一次任务表,到时间就执行对应的命令。它不需要额外安装,大多数发行版默认自带,适合所有“到点就做”的重复任务。
与手动执行相比,crontab 的价值在于稳定:只要服务器在运行、cron 服务正常,任务就会准时触发,不依赖人工值守。
二、时间表达式:五个字段
crontab 每行任务由“时间 + 命令”组成,时间部分有五个字段,从左到右依次是:
分 时 日 月 周
* * * * * 要执行的命令
| 字段 | 取值范围 | 说明 |
|---|---|---|
| 分 | 0–59 | 第几分钟 |
| 时 | 0–23 | 第几个小时 |
| 日 | 1–31 | 一个月中的第几天 |
| 月 | 1–12 | 第几个月 |
| 周 | 0–7(0 和 7 都表示周日) | 一周中的第几天 |
每个字段支持几种写法:
*:表示“每一个”,如分钟字段写*就是每分钟;,:枚举多个值,如1,15表示第 1 和第 15;-:表示范围,如1-5表示 1 到 5;/:表示步长,如*/10表示每 10 个单位。
几个最常用的例子:
# 每天凌晨 2 点 30 分执行备份脚本
30 2 * * * /home/user/backup.sh
# 每 10 分钟检查一次服务状态
*/10 * * * * /home/user/check.sh
# 每周一早上 9 点清理临时文件
0 9 * * 1 rm -rf /tmp/*
# 每月 1 号凌晨 3 点生成上月报表
0 3 1 * * /home/user/report.sh
# 工作日(周一到周五)每小时执行一次
0 * * * 1-5 /home/user/sync.sh
注意一个细节:当“日”和“周”两个字段同时被限定(都不是 *)时,cron 是“或”的关系——满足其中任意一个条件就执行,而不是同时满足。
三、基本操作命令
crontab -e # 编辑当前用户的任务表
crontab -l # 查看当前用户的任务表
crontab -r # 删除当前用户的全部任务(危险,执行前先备份)
crontab -e 默认用 vi 打开编辑器,不熟悉 vi 的新手可以先设置编辑器:
export EDITOR=nano
crontab -e
编辑完成后保存退出,任务立即生效,不需要重启任何服务。想确认 cron 服务本身是否在运行:
systemctl status cron # Debian / Ubuntu
systemctl status crond # CentOS / RHEL
四、写任务时最容易踩的四个坑
1. 环境变量和 PATH 不一样
cron 执行任务时的环境变量比交互式 Shell 少得多,PATH 也很短。直接在任务里写 python3、node 这类命令可能找不到。稳妥的做法有两种:
- 写命令的绝对路径,如
/usr/bin/python3 /home/user/script.py; - 在脚本开头自己设定好
PATH和需要的环境变量。
2. 相对路径会失效
cron 任务的工作目录一般是用户家目录,脚本里用相对路径读写文件很容易跑偏。脚本里的路径一律写绝对路径,或者在脚本开头用 cd 切换到固定目录。
3. 输出没地方去,等于没法排错
命令的标准输出和错误输出默认会发邮件给任务所属用户,多数服务器没配邮件服务,输出就丢了。正确做法是把输出重定向到日志文件:
30 2 * * * /home/user/backup.sh >> /var/log/backup.log 2>&1
这样任务有没有跑、跑没跑成,都能在日志里查到。也可以在脚本内部自己写日志,效果一样。
4. 任务执行时间比间隔长会重叠
如果一个任务每 5 分钟跑一次,但某次执行花了 8 分钟,下一次会在上一次还没结束时启动,两个进程可能互相干扰。需要避免重叠时,可以在脚本里加锁文件,或者用 flock 命令:
*/5 * * * * flock -n /tmp/mytask.lock /home/user/task.sh
flock -n 的意思是拿不到锁就直接退出,不会堆积。
五、一个完整的实战例子:每天自动备份
假设要每天凌晨 2 点备份网站目录并保留最近 7 天的备份,可以写两个文件。
备份脚本 /home/user/backup.sh:
#!/bin/bash
DATE=$(date +%Y%m%d)
tar -czf /home/user/backup/site-$DATE.tar.gz /var/www/html
# 删除 7 天前的旧备份
find /home/user/backup -name "site-*.tar.gz" -mtime +7 -delete
echo "$(date): backup done" >> /var/log/backup.log
记得给脚本加执行权限:chmod +x /home/user/backup.sh。
crontab 里加一行:
0 2 * * * /home/user/backup.sh >> /var/log/backup.log 2>&1
配置完第二天早上检查一下日志文件,确认备份文件确实生成了,这个定时任务就算落地了。
六、什么时候不用 crontab
crontab 适合分钟级到天级的固定周期任务,但不适合以下场景:
- 秒级调度:cron 最小粒度是 1 分钟,需要秒级触发可以用 systemd timer,或者在脚本里自己循环加 sleep;
- 任务依赖复杂:多个任务之间有先后顺序、需要重试和告警时,用 Airflow、xxl-job 这类专业调度工具更合适;
- 只执行一次的任务:用
at命令更直接,如echo "reboot" | at 03:00。
小结
crontab 的核心就三点:五个时间字段的写法、写任务时用绝对路径并记日志、执行时间可能重叠时加锁。掌握这三点,日常的备份、清理、同步、巡检任务基本都能交给它自动跑。建议从一条最简单的定时任务开始,先让日志证明它确实在跑,再逐步把更多重复工作交出去。
- 点赞
- 收藏
- 关注作者
评论(0)