服务计时器文件不适用于 systemd

服务计时器文件不适用于 systemd

我正在学习 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=,可以定义一个定期运行的计时器,并每次激活特定的服务。

这就是为什么您通常会看到OnBootSecOnUnitActiveSec结合使用:这意味着“系统启动后 N 秒启动,然后此后每 M 秒执行一次”。

或者,您可以使用OnCalendar条目来实现相同的目的:

[Timer]
OnCalendar = *-*-* *:*:00/10

这将每 10 秒运行一次。

相关内容