用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