一、cron 到底是干嘛的
- 核心作用 :Linux 自带的自动循环执行命令 / 脚本工具,替代人工重复干活(不用半夜爬起来手动备份数据库、删日志)。
- 守护进程:后台常驻程序叫
crond,我们操作的命令是crontab。 - 四大优点
- 不用额外装软件,系统自带
- 几十年老工具,极其稳定不容易崩
- 几乎不占 CPU 内存,资源消耗极小
- 服务器重启后,定时任务自动恢复继续跑
二、服务安装、启停全套命令(CentOS/RHEL)
1. 安装(没装的时候执行)
yum -y install cronie crontabs
2. 日常管理命令
systemctl start crond # 启动定时服务
systemctl stop crond # 关闭
systemctl restart crond # 重启
systemctl reload crond # 改了配置重载生效
systemctl status crond # 查看服务有没有正常运行
systemctl enable crond # 设置开机自启(必开)
三、两类配置方式:系统全局目录 vs 用户个人任务
1. 系统全局定时目录(/etc/ 下)
cron.d/ # 放自定义零散定时任务(企业批量管理最爱)
cron.daily/ # 每天自动执行一次脚本
cron.hourly/ # 每小时执行
cron.weekly/ # 每周执行
cron.monthly/ # 每月执行
vim /etc/crontab #打开进入下面的这个页面

这是 Linux 系统全局定时任务总配置文件 :/etc/crontab 专门用来配置全系统生效 的 cron 计划任务,和 crontab -e(仅当前用户)不一样,它的格式多了执行用户名字段。
重点:/etc/cron.d/ 里写任务必须指定执行用户名,格式比用户 crontab 多一列用户名。
2. 用户个人定时任务
每个 Linux 账号都有自己独立的定时表,文件存在 /var/spool/cron/用户名 里。
常用 crontab 操作命令
crontab -e # 编辑当前登录用户的定时任务(最常用)
crontab -l # 列出当前用户所有定时任务
crontab -u 用户名 -e # 编辑指定其他用户的定时任务(root才能用)
crontab -r # 删除当前用户全部定时(慎用)
3.区别(容易搞混)
crontab -e:编辑当前用户私有定时任务,格式没有用户名那一列vim /etc/crontab:编辑系统公共定时任务,必须指定执行用户
四、核心语法:5 个星号到底代表啥(重中之重)
格式规则
分 时 日 月 周 要执行的命令/脚本
* * * * * command
从上到下对应:
- 第 1 位:分钟
0-59 - 第 2 位:小时
0-23 - 第 3 位:每月几号
1-31 - 第 4 位:月份
1-12 - 第 5 位:星期几
0-7(0 和 7 都代表周日)
4 个特殊符号解释
*所有值都匹配:比如小时位写*= 每一小时都执行,多个离散时间:1,5,10= 第 1、5、10 分钟分别跑一次-连续范围:8-18= 8 点到 18 点之间/间隔频率:*/10分钟位 = 每 10 分钟跑一次;0-23/2= 每 2 小时跑一次
例:
00 05 * * * 每天凌晨5点整执行
58 23 * * * 每天晚上23点58分执行脚本(比如备份)
*/30 18-23 * * * 每天18点到23点,每30分钟跑一次
0 1 * * 6,0 每周六、周日凌晨1点执行
五、写定时任务的进阶实用写法(生产必用)
1. 日志输出重定向(必须加)
默认 cron 不会打印日志,加 >> 日志文件 2>&1 把正常输出 + 报错都存下来,方便排查失败原因
58 23 * * * /home/work/update.sh >> /home/work/log/update.log 2>&1
2. nohup 和 & 后台挂起
-
nohup:忽略终端输入,防止脚本卡在等待输入的状态 -
末尾
&:完全丢后台运行,不占用会话58 23 * * * nohup /home/work/update.sh >> /home/work/log/update.log 2>&1 &
3. 按日期拆分日志文件(避文件过大)
⚠️ 大坑 :crontab 里 % 符号必须加反斜杠 \ 转义,否则直接执行失败 正确写法:
58 23 * * * nohup /home/work/update.sh >> "/home/work/log/update_$(date +\%Y\%m\%d).log" 2>&1 &
4. 重启后只执行一次的任务
两种方式:
- 写入
/etc/rc.local文件,系统开机自动跑里面命令 - 在
/etc/cron.d/配置 @reboot 规则
六、企业高频实例
1、MySQL 每日凌晨 2 点全库备份,自动删 7 天前旧备份
# 凌晨2点备份数据库并压缩
0 2 * * * /usr/bin/mysqldump -uroot -p密码 --all-databases | gzip > /backup/mysql_$(date +\%Y\%m\%d).sql.gz
# 凌晨3点删除7天以上的备份包
0 3 * * * find /backup -name "mysql_*.sql.gz" -mtime +7 -delete
2、系统日志自动清理
# 每天1点压缩7天前的日志
0 1 * * * find /var/log -name "*.log" -mtime +7 -exec gzip {} \;
# 每周3点删除30天前压缩包
0 3 * * 0 find /var/log -name "*.gz" -mtime +30 -delete
技巧
- 只工作日(周一到周五)9-18 点执行:
0 9-18 * * 1-5 脚本路径- 随机延迟执行,避免凌晨大量服务器同时跑备份挤爆 IO:
0 2 * * * sleep $((RANDOM%300)) && 备份脚本- 满足文件存在才执行任务:
*/10 * * * * [ -f /tmp/run_flag ] && 脚本
七、最容易踩坑的致命问题:环境变量不生效
现象
手动在命令行跑脚本完全正常,放到 crontab 定时就死活不执行、报错找不到命令。
原因
cron 执行时不会加载用户的.bash_profile、/etc/profile 这些系统环境变量,找不到 java、mysql、自定义 PATH 路径。
3 种解决办法(任选其一)
1、脚本里写绝对路径:所有文件、程序全部写完整全路径,不要用相对路径
3、脚本开头主动加载环境变量
#!/bin/bash
source /etc/profile # 加载全局环境变量
export 自定义变量=xxx
# 下面再写业务命令
3、直接在 crontab 任务开头加载环境
0 * * * * . /etc/profile && /bin/sh 你的脚本路径
cron 执行完整流程
crond 守护进程每分钟扫描一次:
- 读取系统全局配置
/etc/crontab- 扫描
/etc/cron.d/所有文件- 读取
/var/spool/cron/所有用户个人定时任务- 核对时间是否匹配,匹配就创建子进程执行对应命令