Day 6-3 定时任务 Cron 和 Systemd Timer
掌握 Linux 定时任务配置方法,能够使用 Cron 和 Systemd Timer 实现任务自动化。

课程目标
- 掌握 Cron 定时任务的配置方法。
- 理解 Systemd Timer 的工作原理。
- 掌握 Systemd Timer 的配置方法。
- 了解 Cron 和 Systemd Timer 的选型建议。
一、定时任务概述
1.1 什么是定时任务?
运维工作中经常需要在固定时间执行某些任务:每天凌晨备份日志、每小时清理临时文件、每周一发送报表……这些重复性工作可以用定时任务自动完成。
Linux 中两种主流定时任务方案:

| 对比项 | Cron | Systemd Timer |
|---|---|---|
| 出现时间 | 传统(Unix 时代) | 现代(Systemd 时代) |
| 配置方式 | crontab 文件 | .timer + .service 单元 |
| 精度 | 分钟级 | 秒/微秒级 |
| 日志集成 | 需手动配置 | 自动集成 journalctl |
| 依赖管理 | ❌ 不支持 | ✅ 支持 |
| 错过执行补偿 | ❌ 不支持 | ✅ 支持 |
二、Cron 定时任务
2.1 Cron 是什么?
Cron 是 Linux 系统中最经典的定时任务工具,通过 crond 守护进程每分钟检查一次是否有任务需要执行。
2.2 三种配置位置
| 配置位置 | 用途 | 编辑方式 |
|---|---|---|
| crontab -e | 用户级定时任务 | 每个用户独立,保存在 /var/spool/cron/用户名 |
| /etc/crontab | 系统级定时任务 | 需 root 权限编辑 |
| /etc/cron.d/ | 应用级定时任务 | 每个应用独立文件,便于管理 |
2.3 时间字段格式
* * * * * 命令
┊ ┊ ┊ ┊ ┊
┊ ┊ ┊ ┊ └─── 星期几 (0-7, 0 和 7 都表示周日)
┊ ┊ ┊ └───── 月份 (1-12)
┊ ┊ └─────── 日期 (1-31)
┊ └───────── 小时 (0-23)
└─────────── 分钟 (0-59)
2.4 特殊字符
| 字符 | 含义 | 示例 |
|---|---|---|
* |
任意值 | * * * * * 每分钟 |
, |
列举多个值 | 1,15,30 * * * * 每小时的第 1、15、30 分钟 |
- |
范围 | 10-15 * * * * 每小时的第 10 到 15 分钟 |
/ |
步长 | */5 * * * * 每 5 分钟 |
2.5 常见示例
# 每天凌晨 2:30 执行备份
30 2 * * * /usr/local/bin/backup.sh
# 每小时执行一次
0 * * * * /usr/local/bin/hourly_task.sh
# 每周一凌晨 3:00 执行
0 3 * * 1 /usr/local/bin/weekly_report.sh
# 每月 1 号凌晨 4:00 执行
0 4 1 * * /usr/local/bin/monthly_cleanup.sh
# 每 5 分钟执行一次
*/5 * * * * /usr/local/bin/check_status.sh
三、Cron 实战案例(备份日志)
通过一个实际案例,直观感受 Cron 是如何工作的。
3.1 准备工作
# 创建备份目录
[root@magedu ~]# mkdir -p /backup
# 查看要备份的日志目录
[root@magedu ~]# ls -la /var/log/
3.2 创建 Cron 任务
# 编辑当前用户的 crontab
[root@magedu ~]# crontab -e
添加以下行(每天凌晨 2:00 备份日志,文件名带日期和来源标识):
0 2 * * * /usr/bin/tar -czf /backup/logs-cron-$(date +\%F).tar.gz /var/log/ 2>/dev/null
注意:在 crontab 中,% 有特殊含义(表示换行),必须用 \% 转义。
3.3 验证 Cron 执行结果
# 查看当前任务列表
[root@magedu ~]# crontab -l
0 2 * * * /usr/bin/tar -czf /backup/logs-cron-$(date +\%F).tar.gz /var/log/ 2>/dev/null
# 手动执行测试(临时替换日期,验证命令是否正确)
[root@magedu ~]# date -s 20260725
[root@magedu ~]# /usr/bin/tar -czf /backup/logs-cron-test.tar.gz /var/log/ 2>/dev/null
[root@magedu ~]# ls -l /backup/logs-cron-test.tar.gz
-rw-r--r-- 1 root root 123456 Jul 18 14:30 /backup/logs-cron-test.tar.gz
# 查看 cron 服务日志
[root@magedu ~]# tail -f /var/log/cron
四、Systemd Timer
4.1 什么是 Systemd Timer?
Systemd Timer 是 Systemd 内置的定时任务机制,由一个 .timer 单元(定义触发时间)和一个 .service 单元(定义执行内容)配对工作。

4.2 Timer 的触发方式
| 触发方式 | 说明 | 示例 |
|---|---|---|
| OnCalendar | 日历触发,类似 Cron 的时间表达式 | --* 02:00:00 每天凌晨 2 点(原文写法) |
| OnBootSec | 系统启动后延迟触发 | OnBootSec=5min |
| OnUnitActiveSec | 服务上次激活后延迟触发 | OnUnitActiveSec=1h |
4.3 实战:每天凌晨备份日志(与 Cron 对比)
最小化安装后,没有 tar。手动安装 dnf -y install tar。
第一步:创建备份脚本
# 1. 创建备份脚本
[root@magedu ~]# cat > /opt/backup.sh << 'EOF'
#!/bin/bash
/usr/bin/tar -czf /backup/logs-timer-$(date +%F).tar.gz /var/log/ 2>/dev/null
EOF
[root@magedu ~]# chmod +x /opt/backup.sh
第一步:创建 Service 单元(原文编号)
[root@magedu ~]# vim /etc/systemd/system/backup-timer.service
[Unit]
Description=Log Backup Service (Timer)
[Service]
Type=oneshot
ExecStart=/opt/backup.sh
User=root
Type=oneshot 表示任务执行一次即退出,适合定时任务。
第二步:创建 Timer 单元
[root@magedu ~]# vim /etc/systemd/system/backup-timer.timer
[Unit]
Description=Log Backup Timer
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
| 参数 | 含义 |
|---|---|
| OnCalendar=daily | 每天触发一次(相当于 00:00:00) |
| Persistent=true | 如果系统在计划时间关机,开机后立即补执行 |
第三步:启动 Timer
[root@magedu ~]# systemctl daemon-reload
[root@magedu ~]# systemctl enable backup-timer.timer
[root@magedu ~]# systemctl start backup-timer.timer
4.4 验证 Systemd Timer 执行结果
# 查看所有 timer
[root@magedu ~]# systemctl list-timers
NEXT LEFT LAST PASSED UNIT
Sat 2026-07-25 01:22:07 CST 59min Fri 2026-07-24 07:25:00 CST 59min ago dnf-makecache.timer >
Sat 2026-07-25 01:30:34 CST 1h 8min Sat 2026-07-25 00:00:00 CST 22min ago fwupd-refresh.timer >
Sat 2026-07-25 22:22:07 CST 21h Fri 2026-07-24 07:25:00 CST 2h 0min ago systemd-tmpfiles-clean.timer >
Sun 2026-07-26 00:00:00 CST 23h - - backup-timer.timer >
Sun 2026-07-26 00:08:39 CST 23h Sat 2026-07-25 00:21:53 CST 19s ago logrotate.timer >
Mon 2026-07-27 01:38:13 CST 2 days Wed 2026-07-22 19:05:49 CST - fstrim.timer >
6 timers listed.
Pass --all to see loaded but inactive timers, too.
[root@magedu ~]# systemctl list-timers
NEXT LEFT LAST PASSED UNIT
Sat 2026-07-25 01:22:07 CST 59min Fri 2026-07-24 07:25:00 CST 59min ago dnf-makecache.timer >
Sat 2026-07-25 01:30:34 CST 1h 8min Sat 2026-07-25 00:00:00 CST 22min ago fwupd-refresh.timer >
Sat 2026-07-25 22:22:07 CST 21h Fri 2026-07-24 07:25:00 CST 2h 0min ago systemd-tmpfiles-clean.timer >
Sun 2026-07-26 00:00:00 CST 23h - - backup-timer.timer >
Sun 2026-07-26 00:08:39 CST 23h Sat 2026-07-25 00:21:53 CST 19s ago logrotate.timer >
Mon 2026-07-27 01:38:13 CST 2 days Wed 2026-07-22 19:05:49 CST - fstrim.timer >
6 timers listed.
Pass --all to see loaded but inactive timers, too.
backup-timer.timer 状态确认:
| 字段 | 值 | 含义 |
|---|---|---|
| NEXT | Sun 2026-07-26 00:00:00 CST | 下次执行时间(明天凌晨 0 点) |
| LEFT | 23h | 还有约 23 小时 |
| LAST | - | 从未执行过 |
| PASSED | - | 从未执行过 |
一切正常 ✅
backup-timer.timer 已经启用并等待执行。
- 下次执行:明天(7 月 26 日)凌晨 0:00。
- 这是 OnCalendar=daily 的正确行为(每天 00:00:00 触发)。
如果想立即测试:
# 手动触发一次(不等待 timer)
[root@magedu ~]# systemctl start backup-timer.service
# 查看日志(自动集成 journalctl)
[root@magedu ~]# journalctl -u backup-timer.service -n 20
# 查看生成的备份文件
[root@magedu ~]# ls -l /backup/
total 724
-rw-r--r--. 1 root root 741207 Jul 25 00:34 logs-timer-2026-07-25.tar.gz
五、Cron vs Systemd Timer 对比演示

| 对比项 | Cron | Systemd Timer |
|---|---|---|
| 生成的备份文件 | /backup/logs-cron-日期.tar.gz | /backup/logs-timer-日期.tar.gz |
| 配置方式 | 一行 crontab | 两个单元文件 |
| 日志查看 | tail -f /var/log/cron | journalctl -u backup-timer.service |
| 适用场景 | 简单任务 | 复杂任务 |
六、OnCalendar 时间表达式
| 表达式 | 含义 |
|---|---|
| daily | 每天 00:00:00 |
| weekly | 每周一 00:00:00 |
| monthly | 每月 1 号 00:00:00 |
| hourly | 每小时整点 |
| boot | 系统启动时 |
--* 02:00:00 |
每天凌晨 2 点(原文写法) |
Mon..Fri 09:00:00 |
工作日上午 9 点 |
*-*-01 04:00:00 |
每月 1 号凌晨 4 点 |
七、Cron vs Systemd Timer 选型建议

| 场景 | 推荐方案 | 原因 |
|---|---|---|
| 简单单条命令 | Cron | 配置简单,一行搞定 |
| 日常运维脚本 | Cron | 习惯使然,够用 |
| 需要依赖其他服务 | Systemd Timer | 可指定 After= |
| 需要详细日志追踪 | Systemd Timer | 自动集成 journalctl |
| 需要秒级精度 | Systemd Timer | Cron 只能到分钟 |
| 需要错过执行补偿 | Systemd Timer | Persistent=true |
八、Rocky vs Ubuntu 差异
| 对比项 | Rocky 10 | Ubuntu 26.04 |
|---|---|---|
| crond 服务名 | crond | cron |
| 查看 cron 日志 | /var/log/cron | /var/log/syslog(grep cron) |
| systemctl 命令 | 同左 | 同左 |
| journalctl 命令 | 同左 | 同左 |
九、课后作业
必做
- 创建一个 Cron 任务:每天凌晨 2:00 备份
/var/log目录,生成 logs-cron-日期.tar.gz。 - 创建一个 Systemd Timer:每天凌晨 3:00 备份
/var/log目录,生成 logs-timer-日期.tar.gz。 - 查看 cron 日志,确认任务执行记录。
- 使用 journalctl 查看 timer 执行日志。
- 对比两种方案生成的备份文件。
简答题
1. Cron 执行命令时为什么要使用绝对路径?
Cron 使用最小化环境,PATH 只有 /usr/bin 和 /bin,不会读取用户的环境变量。使用绝对路径可以确保命令被正确找到。
2. 在 crontab 中 % 为什么要转义?
Cron 中 % 表示换行符,如果不转义会导致命令被截断。需要用 \% 转义。
3. 什么场景下应该选 Cron?什么场景下应该选 Systemd Timer?
简单单条命令选 Cron,配置简单。需要依赖管理、日志追踪、错过补偿的复杂任务选 Systemd Timer。
评论