Pau*_*aul 9 systemd systemd-timers
我有几个服务(静态站点生成器),我想从同一个 systemd 计时器定期触发它们。我找到了这个问题/答案,它准确地涵盖了我想要做的事情,并描述了一个设置,其中多个服务的.target
文件Wants=
由相应的计时器触发。这听起来不错,但我发现当我实际设置它时,它只会触发一次,然后自行禁用!
我准备了一个最小的工作示例(这不会触发多个服务,但演示了相同的问题):
\ntest-timer.timer
:
[Unit]\nDescription=A test timer\n\n[Timer]\nOnCalendar=*-*-* *:*:30\nUnit=test-timer.target\n\n[Install]\nWantedBy=timers.target\n
Run Code Online (Sandbox Code Playgroud)\ntest-timer.target
:
[Unit]\nDescription=Target unit\nWants=test-timer.service\nAfter=test-timer.service\n\n[Install]\nWantedBy=timers.target\n
Run Code Online (Sandbox Code Playgroud)\ntest-timer.service
:
[Unit]\nDescription=Run test\n\n[Service]\nExecStart=/usr/bin/bash -c "date --rfc-3339=\'seconds\' >> /tmp/test-timer-output"\n\n[Install]\nAlso=test-timer.target\n
Run Code Online (Sandbox Code Playgroud)\n启用定时器:
\n$ sudo cp test-timer.* /etc/systemd/system/\n$ sudo systemctl enable --now test-timer.timer\nCreated symlink /etc/systemd/system/timers.target.wants/test-timer.timer \xe2\x86\x92 /etc/systemd/system/test-timer.timer.\n
Run Code Online (Sandbox Code Playgroud)\nsystemctl list-timers --all
然后,当我在第一次运行之前查看 的输出时,我得到(忽略其他计时器):
NEXT LEFT LAST PASSED UNIT ACTIVATES\nFri 2021-10-08 10:38:30 EDT 21s left n/a n/a test-timer.timer test-timer.target\n
Run Code Online (Sandbox Code Playgroud)\n第一次运行后,NEXT
和LEFT
已替换为n/a
:
NEXT LEFT LAST PASSED UNIT ACTIVATES\nn/a n/a Fri 2021-10-08 10:38:32 EDT 1min 5s ago test-timer.timer test-timer.target\n
Run Code Online (Sandbox Code Playgroud)\n我还尝试添加Persistent=true
和test-timer.target
显式启用test-timer.target
,但这些都不起作用。每当我这样做时systemctl restart test-timer.timer
,它都会重新启动,但只会触发一次运行,然后再也不会运行。
如果我通过更改toUnit=
行来删除间接层,该服务会很高兴地按预期每分钟触发一次。test-timer.timer
Unit=test-timer.service
我是否缺少某些配置或安装步骤?
\n在 Twitter 上获得一些帮助后,我成功解决了这个问题。问题是 systemd计时器只会激活不活动的服务,而目标的默认行为是激活并保持活动状态,除非有什么原因导致其停机(它与单元的生命周期无关Wants=
)。要在目标单元激活的任何服务变为非活动状态时强制目标单元变为非活动状态,请在上面的示例中BindsTo=
使用 代替。Wants=
因此,对于这个最小的例子:
test-timer.target
:
[Unit]
Description=Target unit
BindsTo=test-timer.service
After=test-timer.service
[Install]
WantedBy=timers.target
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
然后您可以看到,一旦test-timer.service
运行完毕,test-timer.target
也将变为inactive
(因此计时器将能够再次激活它):
$ sudo systemctl list-units --all test-timer.target test-timer.service
UNIT LOAD ACTIVE SUB DESCRIPTION
test-timer.service loaded inactive dead Run test
test-timer.target loaded inactive dead Target unit
Run Code Online (Sandbox Code Playgroud)
而在更改之前,目标在服务终止后仍保持活动状态:
$ sudo systemctl list-units --all test-timer.target test-timer.service
UNIT LOAD ACTIVE SUB DESCRIPTION
test-timer.service loaded inactive dead Run test
test-timer.target loaded active active Target unit
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2605 次 |
最近记录: |