使用 systemd Timers 执行定时任务

在 Linux 系统上,定时任务通常与 cron 关联。cron 简单易用、广泛可用,至今仍有价值。但在使用 systemd 的现代 Linux 发行版上,还有另一个强大的选项:systemd timers。

systemd timer 可以在指定时间、开机后或固定间隔触发服务。与传统 cron 相比,systemd timers 与系统服务管理器集成更紧密、日志更清晰、调度选项更灵活。

本文介绍 systemd timers 的原理与配置方法。

什么是 systemd Timer?

systemd timer 是一种单元文件,用于控制另一个 systemd 单元的激活时机。在大多数情况下,timer 激活的是一个 .service 单元。

一个典型的定时任务需要两个文件:

/etc/systemd/system/example-task.service
/etc/systemd/system/example-task.timer

.service 文件定义要执行什么。.timer 文件定义何时执行。这种分离使得 systemd timers 结构清晰、易于管理。

简单示例:每日备份

假设我们要每天执行一次备份脚本。

首先创建脚本:

sudo nano /usr/local/bin/daily-backup.sh

示例内容:

#!/bin/bash
echo "Backup started at Thu Jun 11 11:23:18     2026" >> /var/log/daily-backup.log
tar -czf /tmp/etc-backup.tar.gz /etc
echo "Backup finished at Thu Jun 11 11:23:18     2026" >> /var/log/daily-backup.log

设置可执行权限:

sudo chmod +x /usr/local/bin/daily-backup.sh

创建 Service 单元

创建服务文件:

sudo nano /etc/systemd/system/daily-backup.service

内容:

[Unit]
Description=Daily backup task

[Service]
Type=oneshot
ExecStart=/usr/local/bin/daily-backup.sh

Type=oneshot 表示服务执行命令后即退出,适合备份、清理、报告等一次性任务。

创建 Timer 单元

创建定时器文件:

sudo nano /etc/systemd/system/daily-backup.timer

内容:

[Unit]
Description=Run daily backup task

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target

OnCalendar=daily 让 systemd 每天运行一次服务。Persistent=true 确保如果机器在计划时间处于关机状态,systemd 会在下次开机后补执行遗漏的任务。

启用和启动 Timer

重新加载 systemd 并启用定时器:

sudo systemctl daemon-reload
sudo systemctl enable --now daily-backup.timer

检查定时器状态:

systemctl status daily-backup.timer

列出所有活跃的定时器:

systemctl list-timers

查看日志

由于任务以 systemd 服务方式运行,日志可通过 journalctl 查看:

journalctl -u daily-backup.service

实时跟踪日志:

journalctl -u daily-backup.service -f

这比手动重定向 cron 输出或检查本地邮件方便得多。

常用 Timer 选项

开机后运行

开机后 5 分钟执行:

OnBootSec=5min

周期性运行

每 30 分钟执行一次:

OnBootSec=5min
OnUnitActiveSec=30min

OnUnitActiveSec 表示在上一次激活后 30 分钟再次运行。

指定时间运行

每天 03:30:

OnCalendar=*-*-* 03:30:00

每周一 04:00:

OnCalendar=Mon 04:00

每月1日 00:00:

OnCalendar=*-*-01 00:00:00

手动测试 Service

在依赖 timer 之前,先手动测试服务:

sudo systemctl start daily-backup.service
systemctl status daily-backup.service
journalctl -u daily-backup.service

禁用和删除 Timer

停止并禁用:

sudo systemctl disable --now daily-backup.timer

完全删除:

sudo rm /etc/systemd/system/daily-backup.service
sudo rm /etc/systemd/system/daily-backup.timer
sudo systemctl daemon-reload

systemd Timer 与 Cron 的对比

Cron 对于简单任务仍然是好选择,尤其在最小化系统上。但 systemd timers 有多项优势:

  • 与系统服务集成更紧密
  • 通过 journalctl 查看日志更方便
  • 可依赖其他 systemd 单元
  • Persistent=true 支持遗漏任务补执行
  • 调度选项更灵活
  • 调度逻辑与任务逻辑清晰分离

对于已使用 systemd 的服务器,timers 往往是更整洁、更易维护的方案。

总结

systemd timers 是 Linux 上管理定时任务的现代方案。基本配置只需两个文件:.service 定义任务,.timer 定义调度。理解这个结构后,systemd timers 比传统 cron 更易使用和调试。