在 Ubuntu 22.04 里,cron 和 systemd timer 都能做"定时任务",但它们不是同一个东西。
- cron:老牌、经典、直接按时间规则执行任务
- systemd timer :systemd 原生定时机制,通常搭配
.service使用
如果你只是想"到点执行命令",两者都可以;如果你希望和 systemd 服务管理、日志、启动顺序更好地配合,systemd timer 更现代一些。
一、cron 是什么
cron 是 Linux 里最传统的定时任务服务之一。它的特点是:
- 语法简单
- 适合周期性脚本
- 使用广泛
- 很多老系统和运维脚本都依赖它
cron 的任务通常通过 crontab 管理。
1. 查看当前用户的定时任务
bash
crontab -l
这个命令看到的是当前用户自己的 crontab。
它对应的文件通常在:
bash
/var/spool/cron/crontabs/<用户名>
在 Ubuntu 上,普通用户自己的 crontab 一般保存在:
bash
/var/spool/cron/crontabs/用户名
例如 root 用户:
bash
/var/spool/cron/crontabs/root
注意:这个文件通常不建议直接手工编辑,应该用
crontab -e。
2. 查看系统级的 cron 任务
除了用户自己的 crontab,Ubuntu 还有一些系统级任务文件,常见位置如下:
bash
/etc/crontab
/etc/cron.d/
/etc/cron.hourly/
/etc/cron.daily/
/etc/cron.weekly/
/etc/cron.monthly/
这些地方放的是系统维护类任务,比如日志清理、数据库更新、临时文件清理等。
3. cron 的时间格式
cron 表达式一般长这样:
bash
* * * * * command
顺序是:
text
分 时 日 月 周
例子:每天凌晨 2 点执行一次:
bash
0 2 * * * /usr/local/bin/backup.sh
例子:每 5 分钟执行一次:
bash
*/5 * * * * /usr/local/bin/check.sh
二、systemd timer 是什么
systemd timer 是 systemd 提供的定时功能。它不是单独靠一行 cron 表达式来写,而是通过两个文件配合:
.service:真正执行什么任务.timer:什么时候触发这个任务
简单理解就是:
service负责"干活"timer负责"定时叫它干活"
这套方式更适合现代 Linux 服务管理。
1. 查看已有 timer
bash
systemctl list-timers
如果输出很多,可以这样看:
bash
systemctl list-timers | less
2. timer 的优点
- 能和 systemd 服务统一管理
- 日志可直接用
journalctl看 - 支持开机补跑、延迟启动等能力
- 比 cron 更适合做"服务型任务"
三、cron 和 systemd timer 的区别
可以简单记成:
| 项目 | cron | systemd timer |
|---|---|---|
| 定位 | 传统计划任务 | systemd 原生定时器 |
| 配置方式 | 一行 cron 表达式 | .timer + .service |
| 管理方式 | crontab -e / /etc/crontab |
systemctl enable --now xxx.timer |
| 日志查看 | 依赖系统日志 | journalctl 更直接 |
| 适合场景 | 简单周期任务 | 需要和服务联动的任务 |
一句话总结:
cron 更像"老式闹钟",systemd timer 更像"和系统服务联动的智能闹钟"。
四、cron 的一些常见定时任务
Ubuntu 上,cron 常见用途包括:
- 定时备份数据库
- 定时清理日志
- 定时同步文件
- 定时检查服务状态
- 定时重启某些进程
例如每晚 3 点清理临时文件:
bash
0 3 * * * /usr/local/bin/clean-temp.sh
例如每天凌晨 1 点备份 MySQL:
bash
0 1 * * * /usr/local/bin/mysql-backup.sh
这些都很适合用 cron。
五、如何自定义 systemd timer
下面用一个简单例子说明:定时重启 nginx。
这很适合拿来理解 systemd timer,因为它能很直观看到"service + timer"的组合。
1. 创建 service 文件
先创建一个服务文件:
bash
/etc/systemd/system/nginx-restart.service
内容如下:
ini
[Unit]
Description=Restart Nginx Service
[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl restart nginx
说明:
Type=oneshot表示这是一次性任务ExecStart是实际执行的命令
2. 创建 timer 文件
再创建:
bash
/etc/systemd/system/nginx-restart.timer
内容如下:
ini
[Unit]
Description=Run Nginx Restart Every Day at 3 AM
[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
Unit=nginx-restart.service
[Install]
WantedBy=timers.target
说明:
OnCalendar=*-*-* 03:00:00:每天凌晨 3 点触发Persistent=true:如果机器错过了时间,开机后补跑Unit=:触发哪个 service
3. 启用 timer
bash
systemctl daemon-reload
systemctl enable --now nginx-restart.timer
4. 查看 timer 是否生效
bash
systemctl list-timers | grep nginx-restart
5. 查看日志
如果任务执行了,可以看日志:
bash
journalctl -u nginx-restart.service
六、用 apt 做一个定时示例
如果你想用 apt 做演示,比较合理的方式是:定时更新软件包索引,而不是随便自动升级所有东西。
比如写一个 service 执行:
bash
apt update
service 示例
ini
[Unit]
Description=Run apt update
[Service]
Type=oneshot
ExecStart=/usr/bin/apt update
然后配一个 timer,定时执行即可。
不过要注意:
apt update可以定时跑apt upgrade、apt dist-upgrade要更谨慎- 自动升级系统可能影响生产环境稳定性
如果是生产机,更建议先做告警、检查、备份,再决定是否自动升级。
七、怎么选择
简单判断:
- 任务很简单,只是按时间跑脚本 → 用
cron - 任务希望和 systemd 服务统一管理 → 用
systemd timer - 需要日志、依赖、补跑、服务联动 → 优先
systemd timer - 老项目、老脚本兼容 → 继续用
cron也没问题
八、实际工作里怎么记
你可以这样理解:
crontab -l看的是当前用户自己的 cron 任务- 用户 crontab 实际存放在
/var/spool/cron/crontabs/用户名 - 系统级 cron 任务常放在
/etc/crontab和/etc/cron.d/ systemd timer通过.service + .timer管理- 想定时重启 nginx、执行备份、跑检查任务,systemd timer 很顺手
九、最简结论
text
cron = 传统定时任务
systemd timer = systemd 原生定时器
text
crontab -l 看的是当前用户的 cron 任务,底层通常对应 /var/spool/cron/crontabs/用户名
text
systemd timer 适合"定时触发一个服务",cron 适合"按时间执行一条命令或脚本"