用systemd timer代替crontab
Created 2022-05-23 / Updated 2022-11-23一、用户级的配置:
用户级的文件放在~/.config/systemd/user/下。需要两个配置文件,一个是xxx.service,一个是xxx.timer,两个文件的文件名(即xxx部分)必须保持相同:
$ vi ~/.config/systemd/user/test.service
[Unit]
Description = My Test
[Service]
Type = oneshot
ExecStart = %h/test.sh
[Install]
WantedBy = multi-user.target
Description为描述,可任意填写。
ExecStart为要运行的脚本路径,其中%h等同于$HOME。
$ vi ~/.config/systemd/user/test.timer
[Unit]
Description = My Test
[Timer]
OnCalendar = *-*-* *:*:05
AccuracySec = 30s
[Install]
WantedBy = timers.target
OnCalendar这一行依次为星期 年-月-日 时:分:秒,这里省略了星期,上面内容表示每分钟的05秒运行脚本。
AccuracySec这行表示时间到了之后,不立即执行任务,而是在30秒内等待其它到点的定时任务,然后把这些任务集中起来同时执行。默认AccuracySec = 1min,即1分钟。
与AccuracySec相反的有RandomizedDelaySec,可以把同时到点的定时任务,在一定的时间范围内分散开来执行。默认RandomizedDelaySec = 0,即没有延迟。
支持的时间单位有:
微秒:usec, us, µs
毫秒:msec, ms
秒:seconds, second, sec, s
分:minutes, minute, min, m
时:hours, hour, hr, h
日:days, day, d
周:weeks, week, w
月:months, month, M
年:years, year, y
要运行的脚本:
$ vi ~/test.sh
#!/usr/bin/sh
echo `date` >> ~/out.txt
添加可执行权限:
$ chmod +x ~/test.sh
每次修改配置文件后都要重新加载:
$ systemctl --user daemon-reload
启动定时器:
$ systemctl --user start test.timer
查看状态:
$ systemctl --user status test.timer
开机自动启动定时器:
$ systemctl --user enable test.timer
要使定时器在用户退出登录后仍保持运行,还需如下命令:
# loginctl enable-linger 用户名
可以在test.service文件里加入Environment设置环境变量:
[Service]
Type = oneshot
Environment = PATH=/usr/bin:/bin:%h/bin
ExecStart = %h/test.sh
Environment可以设置多次:
Environment = PATH=/usr/bin:/bin:%h/bin
Environment = ABC=/path/abc.txt
也可以把环境变量写在一个文件里:
$ vi ~/env.txt
PATH=/usr/bin:/bin:/home/xxx/bin
ABC=/path/abc.txt
(我试过,不支持"$HOME"与"%h"之类的变量引用)
然后用EnvironmentFile指定文件的路径:
[Service]
Type = oneshot
EnvironmentFile = %h/env.txt
ExecStart = %h/test.sh
二、系统级的配置:
系统级的文件放在/etc/systemd/system/下。同样需要两个配置文件,一个是xxx.service,一个是xxx.timer,两个文件的文件名(即xxx部分)必须保持相同:
# vi /etc/systemd/system/rebootserver.service
[Unit]
Description = reboot server
[Service]
Type = oneshot
ExecStart = /usr/bin/systemctl reboot
# vi /etc/systemd/system/rebootserver.timer
[Unit]
Description = reboot server
[Timer]
OnCalendar = Sun *-*-* 02:00:00
AccuracySec = 1s
[Install]
WantedBy = timers.target
(每周日凌晨2点自动重启服务器)
重新加载配置文件:
# systemctl daemon-reload
启动定时器:
# systemctl start rebootserver.timer
查看状态:
# systemctl status rebootserver.timer
开机自动启动定时器:
# systemctl enable rebootserver.timer
系统级systemctl命令与用户级相同,只是不需要加上--user。
查看日志:
$ journalctl -r
可以加上--system或--user分别查看系统和用户的日志。
参考:
- https://www.freedesktop.org/software/systemd/man/systemd.timer.html
- https://www.freedesktop.org/software/systemd/man/systemd.time.html