我正在学习 RedHat 教程,并且正在尝试学习如何使用 systemd 执行事件。我创建了以下服务
[Unit]
Description=Script2 Logged-In Users
[Service]
Type=simple
ExecStart=/root/Documents/Scripts/script2
[Install]
WantedBy=muti-user.target
它引用以下脚本
#!/bin/bash
echo "Users logged in as of $(date)" >> ~/Documents/UserFiles/useractivity.txt
who >> ~/Documents/UserFiles/useractivity.txt
当我独立执行时,脚本成功运行,但是当我尝试通过计时器运行它时,它仅在我启动后运行。这是计时器文件
[Unit]
Description=Execute Script2 every 10 seconds
[Timer]
#OnBootSec=10min (run script 10 mins after boot)
#OnCalendar=Mon 2015-*-1 10:00:00 (run script at 10am on 1st day of every month if it's a Monday)
#OnCalendar=*:0/15 (run script every 15 minutes)
OnUnitActiveSec=10s (run script every 10 seconds)
unit=script2.service
这是我在查看服务状态时看到的错误
script2.service - Script2 Logged-In Users
Loaded: loaded (/etc/systemd/system/script2.service; enabled; vendor preset: disabled)
Active: inactive (dead)
Aug 08 15:17:38 localhost.localdomain script2[7918]: /root/Documents/Scripts/script2: line 3: Documents/UserFiles/useractivity.txt: No such file or directory
Aug 08 15:17:38 localhost.localdomain script2[7918]: /root/Documents/Scripts/script2: line 4: Documents/UserFiles/useractivity.txt: No such file or directory
Aug 08 15:17:38 localhost.localdomain systemd[1]: script2.service: main process exited, code=exited, status=1/FAILURE
Aug 08 15:17:38 localhost.localdomain systemd[1]: Unit script2.service entered failed state.
Aug 08 15:17:38 localhost.localdomain systemd[1]: script2.service failed.
Aug 08 15:24:44 localhost.localdomain systemd[1]: Started Script2 Logged-In Users.
Aug 08 15:25:44 localhost.localdomain systemd[1]: Started Script2 Logged-In Users.
Aug 08 15:28:19 localhost.localdomain systemd[1]: Started Script2 Logged-In Users.
Aug 08 15:29:34 localhost.localdomain systemd[1]: Started Script2 Logged-In Users.
Aug 08 15:45:58 localhost.localdomain systemd[1]: Started Script2 Logged-In Users.
这是列出计时器时得到的结果
NEXT LEFT LAST PASSED
Tue 2022-08-09 00:00:00 EDT 8h left Mon 2022-08-08 11:17:23 EDT 4h 40min ago
Tue 2022-08-09 12:16:53 EDT 20h left Mon 2022-08-08 12:16:53 EDT 3h 40min ago
n/a n/a n/a n/a
注意:前两个来自不同的过程。
我不确定为什么计时器不工作。
答案1
当您使用 时OnUnitActiveSecs
,这意味着:
定义相对于计时器单元正在激活的单元上次激活时间的计时器
因为定时器是相对于该装置...上次激活的时间,如果自创建计时器以来尚未启动该单元,则计时器将永远不会触发。
我们可以通过一个简单的例子来实现这一点;如果我exampleservice.service
用这个内容创建:
[Service]
Type = simple
ExecStart = /bin/sh -c 'date >> /tmp/datelog.txt'
并exampleservice.timer
包含以下内容:
[Timer]
OnUnitActiveSec=10s
并启动计时器:
systemctl start exampleservice.timer
我可以看到计时器既没有“下一个”也没有“最后一个”执行时间:
$ systemctl list-timers | grep example
n/a n/a n/a n/a exampleservice.timer exampleservice.service
但如果我启动服务一次:
systemctl start exampleservice
我看到计时器立即有“下一个”执行时间:
$ systemctl list-timers | grep example
Mon 2022-08-08 18:17:15 EDT 9s left n/a n/a exampleservice.timer exampleservice.service
如果我等待 10 秒,我可以看到它正在定期执行:
$ systemctl list-timers | grep example
Mon 2022-08-08 18:17:43 EDT 682ms left Mon 2022-08-08 18:17:33 EDT 9s ago exampleservice.timer exampleservice.service
如果您希望定期执行而不需要先启动服务,请查看文档systemd.timer
:
多个指令可以由相同和不同类型组合而成,在这种情况下,只要任何指定的计时器表达式过去,计时器单元就会触发。例如,通过组合 OnBootSec= 和 OnUnitActiveSec=,可以定义一个定期运行的计时器,并每次激活特定的服务。
这就是为什么您通常会看到OnBootSec
和OnUnitActiveSec
结合使用:这意味着“系统启动后 N 秒启动,然后此后每 M 秒执行一次”。
或者,您可以使用OnCalendar
条目来实现相同的目的:
[Timer]
OnCalendar = *-*-* *:*:00/10
这将每 10 秒运行一次。