![Systemd 计时器连续运行计划服务 2 次,而不是只运行 1 次](https://linux22.com/image/184902/Systemd%20%E8%AE%A1%E6%97%B6%E5%99%A8%E8%BF%9E%E7%BB%AD%E8%BF%90%E8%A1%8C%E8%AE%A1%E5%88%92%E6%9C%8D%E5%8A%A1%202%20%E6%AC%A1%EF%BC%8C%E8%80%8C%E4%B8%8D%E6%98%AF%E5%8F%AA%E8%BF%90%E8%A1%8C%201%20%E6%AC%A1.png)
我有一个nodejs gui程序(不需要用户交互),它需要每小时每40分钟运行一次。假设在 05:40PM、06:40PM、07:40PM 等时间运行。在 Debian 服务器中,我使用以下命令启用了 systemd 计时器:
systemctl --user enable my_program.timer
问题是,调度在给定时间开始并成功完成。但该程序立即再次启动并成功完成。
假设节目于下午 5:40 开始,于下午 5:45 结束。大约一分钟后,比如下午 5:46,程序再次开始并结束。然后下次,也就是下午 6:40,这种情况会再次发生。
这种情况每小时都会发生。另外,如果我重新启动服务器,登录该用户帐户后,程序会立即启动,而不是等待 5 分钟。
- 如何停止第二次自动运行?
- 如何强制重启后5分钟启动?
内容/home/user/schedule.sh
#! /usr/bin/bash
cd /home/user/my_program && DISPLAY=:0 /usr/bin/node ./index.js
内容/home/user/.config/systemd/user/my_program.service
[Unit]
Description=My Program
[Service]
ExecStart=/home/user/schedule.sh
内容/home/user/.config/systemd/user/my_program.timer
[Unit]
Description=My Program Timer
Requires=my_program.service
[Timer]
Unit=my_program.service
OnCalendar=*-*-* *:40:*
OnBootSec=5 minutes
[Install]
WantedBy=timers.target
答案1
让我们在这里关注一个问题:重复运行每小时运行一次。您已经使用了以下语法:
OnCalendar=*-*-* *:40:*
根据man systemd.time
,秒位的通配符表示匹配每小时第 40 分钟的每一秒。您可以使用附带的systemd-analyze
工具来确认这一点,该工具有一个日历子命令:
systemd-analyze calendar --iterations=5 "*-*-* *:40:*"
Normalized form: *-*-* *:40:*
Next elapse: Thu 2020-12-17 17:40:00 EST
(in UTC): Thu 2020-12-17 22:40:00 UTC
From now: 15min left
Iter. #2: Thu 2020-12-17 17:40:01 EST
(in UTC): Thu 2020-12-17 22:40:01 UTC
From now: 15min left
Iter. #3: Thu 2020-12-17 17:40:02 EST
(in UTC): Thu 2020-12-17 22:40:02 UTC
From now: 15min left
Iter. #4: Thu 2020-12-17 17:40:03 EST
(in UTC): Thu 2020-12-17 22:40:03 UTC
From now: 15min left
Iter. #5: Thu 2020-12-17 17:40:04 EST
(in UTC): Thu 2020-12-17 22:40:04 UTC
From now: 15min left
所以这是一个问题。
第二个问题是您已将其包含Requires=
在计时器中。在 中man systed.unit
,该指令的文档Requires=
是这样说的:
如果该单位被激活,[In Requires=] 中列出的单位也将被激活。
因此,这也可能导致目标服务被第二次加载。
提出一个关于时间的新问题——OnBootSec=
这是一个单独的问题。