我有几个服务(静态站点生成器),我想从同一个 systemd 计时器定期触发。我找到了这个问题/答案,它完全涵盖了我想要做的事情,并描述了一个设置,其中多个服务的.target
文件Wants=
由相应的计时器触发。这听起来不错,但我发现当我实际设置它时,它只会触发一次,然后自行禁用!
我准备了一个最小的工作示例(这不会触发多个服务,但演示了相同的问题):
test-timer.timer
:
[Unit]
Description=A test timer
[Timer]
OnCalendar=*-*-* *:*:30
Unit=test-timer.target
[Install]
WantedBy=timers.target
test-timer.target
:
[Unit]
Description=Target unit
Wants=test-timer.service
After=test-timer.service
[Install]
WantedBy=timers.target
test-timer.service
:
[Unit]
Description=Run test
[Service]
ExecStart=/usr/bin/bash -c "date --rfc-3339='seconds' >> /tmp/test-timer-output"
[Install]
Also=test-timer.target
启用计时器:
$ sudo cp test-timer.* /etc/systemd/system/
$ sudo systemctl enable --now test-timer.timer
Created symlink /etc/systemd/system/timers.target.wants/test-timer.timer → /etc/systemd/system/test-timer.timer.
然后,当我查看 的输出时systemctl list-timers --all
,在第一次运行之前我得到(忽略其他计时器):
NEXT LEFT LAST PASSED UNIT ACTIVATES
Fri 2021-10-08 10:38:30 EDT 21s left n/a n/a test-timer.timer test-timer.target
第一次运行后,NEXT
已LEFT
替换为n/a
:
NEXT LEFT LAST PASSED UNIT ACTIVATES
n/a n/a Fri 2021-10-08 10:38:32 EDT 1min 5s ago test-timer.timer test-timer.target
我也尝试过添加Persistent=true
和test-timer.target
明确启用test-timer.target
,但这些都不起作用。任何时候我这样做systemctl restart test-timer.timer
,它都会重新启动,但只会触发一次运行,然后再也不会运行。
Unit=
如果我通过更改 to 的行test-timer.timer
来移除间接层Unit=test-timer.service
,该服务会像预期的那样每分钟愉快地触发自己。
我是否缺少一些配置或安装步骤?
在 Twitter 上获得一些帮助后,我设法解决了这个问题。问题是 systemd计时器只会激活不活动的服务,并且目标的默认行为是激活并保持活动状态,除非有什么东西使它停止运行(它与它的单元的生命周期无关
Wants=
)。如果它激活的任何服务变为非活动状态,要强制目标单元变为非活动状态,请在上面的示例中使用BindsTo=
代替。Wants=
所以,对于这个最小的例子:test-timer.target
:test-timer.service
:然后您可以看到,一旦
test-timer.service
完成运行,test-timer.target
也将变为inactive
(因此计时器将能够再次激活它):而在更改之前,目标在服务终止后保持活动状态: