
systemd.timer 是现代 Linux 系统中更优雅、更可靠的方案。
它不仅能提供更细致的定时策略,还能让你的同步脚本直接享受 systemd 的日志管理(journalctl)和故障重启机制。
我们需要创建两个文件:一个服务文件(定义要干什么)和一个定时器文件(定义什么时候干)。
这个文件告诉系统“如何运行你的程序”。
在 /etc/systemd/system/ 目录下创建一个名为 myscript.service 的文件:
[Unit]
Description=My script
After=network.target
[Service]
Type=oneshot
# 建议使用绝对路径指向你的 Python 虚拟环境和脚本
ExecStart=/opt/myscript/venv/bin/python /opt/myscript/myscript.py
# 运行脚本的系统用户,为了安全,建议不要直接用 root
User=root
# 允许脚本执行的最长时间(例如 10 分钟),超时自动终止防卡死
TimeoutStopSec=600
[Install]
WantedBy=multi-user.target这个文件负责定义时间规则。
建议:文件名与 Service 文件完全一致,只有后缀不同,默认情况下,systemd 会自动寻找与 .timer 同名的 .service 文件。复杂情况下可以手工指定,比如多个timer在不同时候触发同一个service。
在同一个目录(/etc/systemd/system/)下创建 myscript.timer 文件:
[Unit]
Description=Timer to trigger My Service
[Timer]
# 1. 相对定时(可选):系统启动后 5 分钟第一次执行
OnBootSec=5min
# 2. 绝对定时(推荐):每小时执行一次
# 语法类似于 cron:星期 年-月-日 时:分:秒
OnCalendar=*-*-* *:00:00
# 3. 错峰延时(防并发):在设定时间后的 0 到 5 分钟内随机找个时间启动
# 避免多台自动化服务器在整点同时发起执行
RandomizedDelaySec=5min
# 4. 允许错过的任务补跑:如果服务器关机错过了某次同步,开机后立刻补跑
Persistent=true
# 5. 强制指定要拉起哪一个服务,如果与service名称相同可忽略
Unit=myscript.service
[Install]
WantedBy=timers.target注:常用触发参数
触发参数 | 基于什么时间戳? | 最适合什么场景? |
|---|---|---|
OnCalendar | 现实世界的墙上时钟 (Wall Clock) | 每天凌晨 2 点捞取全量配置、每周日备份、每整点同步。 |
OnBootSec | 系统开机时刻 (Boot Time) | 开机冷启动后延迟一会,避开系统启动IO高峰。 |
OnActiveSec | Timer启动时刻 | 定时器自己刚跑起来时做一次初始化。 |
OnUnitActiveSec | Service启动时刻 | 每隔 10 分钟或半小时定期巡检(不关心整点)。 |
OnUnitInactiveSec | Service结束时刻 | 脚本耗时不固定,需要“等我跑完,再隔X分钟跑下次”。 |
以xxxSec结尾的触发参数,时间单位和写法。
可以组合使用,比如1m 30s
单位 | 标准全称 | 允许的缩写/别名 | 示例 |
|---|---|---|---|
秒 | seconds | second, sec, s | 30s |
分钟 | minutes | minute, min, m | 15min, 15m |
小时 | hours | hour, hr, h | 2h, 12hr |
天 | days | day, d | 7d, 1day |
周 | weeks | week, w | 2w, 1week |
月 | months | month | 1month, 3months |
年 | years | year, y | 1y, 1year |
第三步、启动与管理
# 1. 重新加载 systemd 配置(每次修改文件后都要执行)
sudo systemctl daemon-reload
# 2. 启动并允许开机自启定时器(注意:是启动 .timer,不是 .service)
sudo systemctl enable --now myscript.timer日常运维常用命令
查看当前系统有哪些定时器在跑(以及下次执行时间):
systemctl list-timers --all你会看到类似下面的输出,清晰地显示NEXT(下次执行时间)和 LEFT(倒计时):

:
手动立刻触发一次同步(测试脚本是否有 Bug)不需要去改时间,直接手动拉起 Service 即可:
sudo systemctl start myscript.service查看同步脚本输出的日志(排查网络连接或 API 报错):
# 查看该服务的所有历史日志
journalctl -u myscript.service
# 实时滚动查看最近的日志
journalctl -u myscript.service -f