UFSの備忘録 % Home / Categories

用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分别查看系统和用户的日志。

参考:

Categories: [Linux]