systemd timer 不是 cron 的一键替换,需配对定义.timer与.service文件、显式声明环境变量及路径,并用journalctl查service日志排错。

systemd timer 不是 cron 的“一键替换”,而是需要配对定义、显式声明环境、并借助 journalctl 排查的现代调度方案。它不读取 crontab 文件,也不继承 shell 环境,直接照搬 cron 写法大概率静默失败。
必须写两个文件:.timer + .service
这是最核心的规则,缺一不可:
- .timer 文件只管“什么时候触发”,内容里不能写命令,只能指定时间逻辑(如 OnCalendar=--* 03:00:00)和补执行策略(Persistent=true)
- .service 文件只管“具体干什么”,Type 必须是 oneshot,ExecStart 必须是完整可执行路径(不能写
ls -l,得写/bin/ls -l或封装进脚本) - 两个文件名要一致(如
backup.timer和backup.service),放在/etc/systemd/system/(系统级)或~/.config/systemd/user/(用户级)
时间表达式更直观,但别依赖模糊词
systemd 支持自然语言风格的时间写法,比 cron 的五段式更易读:
在无 root/sudo 权限的环境(云容器、VPS、隔离主机)中安装并配置 OpenClaw 浏览器工具的 headless Chrome。适用场景:...
-
每天凌晨 2:15 →
OnCalendar=*-*-* 02:15:00 -
每周一到周五上午 9 点 →
OnCalendar=Mon..Fri 09:00:00 -
开机后 10 分钟执行一次 →
OnBootSec=10min - 慎用
hourly这类预设值,它实际等价于*-*-* *:00:00,可能和你理解的“每小时整点”有偏差
环境变量、路径、Shell 特性必须手动声明
cron 默认用 /bin/sh 解析命令,且自动加载用户环境;systemd service 完全不走 shell,也不读 ~/.bashrc 或 /etc/environment:
- 加 Environment="PATH=/usr/local/bin:/usr/bin:/bin",否则常见命令如
python3或jq会报Command not found - 加 WorkingDirectory=/root(或你的目标目录),避免脚本因相对路径失败
- 不要在
ExecStart=里写管道、变量展开、重定向(如echo $HOME | mail -s "x" y),这些在 systemd 下不生效;应把逻辑移到独立脚本中 - 用户级 timer 需运行
systemctl --user daemon-reload才能识别,且首次启用前要先登录一次或启动 user session
启用、调试、排错三步不能跳
写完文件只是开始,后续操作决定任务是否真能跑起来:
- 重载配置:
sudo systemctl daemon-reload(系统级)或systemctl --user daemon-reload(用户级) - 启用并启动:
sudo systemctl enable --now myjob.timer - 检查状态:
systemctl list-timers --all看是否列出来、下次触发时间是否合理 - 查日志:
journalctl -u myjob.service -n 20 -f,不是 timer 单元,是 service 单元的日志——这是最常被忽略的关键点

















