Day 6-3 定时任务 Cron 和 Systemd Timer

Day 6-3 定时任务 Cron 和 Systemd Timer 掌握 Linux 定时任务配置方法,能够使用 Cron 和 Systemd Timer 实现任务自动化。 课程目标 掌握 Cron 定时任务的配置方法。 理解 Systemd Timer 的工作原理。 掌握 Systemd Time

Day 6-3 定时任务 Cron 和 Systemd Timer

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

Systemd Timers vs Cron

课程目标

  • 掌握 Cron 定时任务的配置方法。
  • 理解 Systemd Timer 的工作原理。
  • 掌握 Systemd Timer 的配置方法。
  • 了解 Cron 和 Systemd Timer 的选型建议。

一、定时任务概述

1.1 什么是定时任务?

运维工作中经常需要在固定时间执行某些任务:每天凌晨备份日志、每小时清理临时文件、每周一发送报表……这些重复性工作可以用定时任务自动完成。

Linux 中两种主流定时任务方案:

定时任务的传统方案 Cron 与现代方案 Systemd Timer

对比项 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 单元(定义执行内容)配对工作。

.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 对比演示

Systemd Timer 与 Cron 备份日志流程

对比项 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 或 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。

评论