我有一个工作的服务,只有在运行之后才工作,因为它dhcpcd.service
执行 github pull,并且除非 DHCP 启动,否则它无法解析主机。network.target
早在 DHCP 服务完成之前就完成了。请注意,当服务应该运行时,用户michael
将不会登录(它是服务器)。
问题是我无法让它运行得足够晚才能工作,而不诉诸一些超长的丑陋延迟来覆盖所有情况,例如
ExecStartPre=sleep 30
Run Code Online (Sandbox Code Playgroud)
这是服务(我尝试过的updatecontinue.service
多种组合之一):After=
# man systemd.service
# man systemd.unit
#
# Debug with (will print errors at the bottom, time is in UTC!):
# -n50 to show 50 lines
# sudo systemctl status updatecontinue
#
# Or to get a plot (open with chrome so its searchable):
# systemd-analyze plot > ~/plot.svg
[Unit]
Description=Check if an update is halfway through, if yes, then update/enable OverlayFS/reboot
[Service]
Type=simple
ExecStart=/home/michael/.venv/terminal/bin/python3 /home/michael/terminal/script/update.py --check
After=dhcpcd.service
User=michael
[Install]
WantedBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)
在这里您可以看到它没有从定义的地方开始:
即使我设置为:
After=dhcpcd.service systemd-update-utmp-runlevel.service systemd-timesyncd.service
Run Code Online (Sandbox Code Playgroud)
systemctl get-default
报告graphical.target
使用此服务:
[Unit]
Description=Check if an update is halfway through, if yes, then update/enable OverlayFS/reboot
[Service]
Type=idle
ExecStart=/home/michael/.venv/terminal/bin/python3 /home/michael/terminal/script/update.py --check
After=default.target
TimeoutStartSec=0
User=michael
[Install]
WantedBy=default.target
Run Code Online (Sandbox Code Playgroud)
结果是:
定义WantedBy=multi-user.target
并After=multi-user.target
添加了一些 systemd 试图解决的冲突。您可以在此答案的下方看到更大的解释/实验。
相反,尝试找出如果服务运行得太早就会失败的原因。运行该服务/目标After=multi-user.target
,而不是运行。After=
After=network.target
我的猜测是,如果您唯一的问题是网络问题,请添加。
如果您需要用户登录,请使用--user
总线。
如果您需要图形会话,请考虑WantedBy=graphical.target
在系统总线或WantedBy=graphical-session.target
用户总线上。
当你使用 时WantedBy=multi-user.target
,它会给出multi-user.target
一种Wants=updatecontinue.service
关系。
这只是意味着:updatecontinue.service
如果已启动,则将启动multi-user.target
。如果updatecontinue.service
启动失败,不影响multi-user.target
。
然后,你给出updatecontinue.service
一个Requires=multi-user.target
关系。这是一个重大冲突。 几乎与(如果你启动这个,那个也会启动)Requires=
相同。除非:如果该单元无法激活,则该单元将不会启动。Wants=
所以你实际上只有两个互相启动的单元,这可能不是你想要的。Requires=
为了清楚起见,我会放弃依赖性。
/关系确实有效,下面是两个服务在没有/Before
的After
情况下进行交互的示例:Before
After
$ systemctl --user cat {early,late}.service
# /home/stew/.config/systemd/user/early.service
[Unit]
Wants=late.service
[Service]
ExecStartPre=sleep 2
ExecStart=sleep 20
# /home/stew/.config/systemd/user/late.service
[Service]
ExecStart=sleep 5
$ systemctl --user start early
$ journalctl --user --since "2 minutes ago" --no-hostname
Mar 08 15:54:42 systemd[1064]: Starting early.service...
Mar 08 15:54:42 systemd[1064]: Started late.service.
Mar 08 15:54:44 systemd[1064]: Started early.service.
Run Code Online (Sandbox Code Playgroud)
可以看到服务同时启动。
现在让我们尝试建立late.service
一个After=early.service
关系:
$ systemctl --user cat {early,late}.service
# /home/stew/.config/systemd/user/early.service
[Unit]
Wants=late.service
[Service]
ExecStartPre=sleep 2
ExecStart=sleep 20
# /home/stew/.config/systemd/user/late.service
[Unit]
After=early.service
[Service]
ExecStart=sleep 5
$ systemctl --user start early
$ journalctl --user --since "2 minutes ago" --no-hostname
Mar 08 16:01:09 systemd[1064]: Starting early.service...
Mar 08 16:01:11 systemd[1064]: Started early.service.
Mar 08 16:01:11 systemd[1064]: Started late.service.
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您可以看到完成late.service
后已开始(等待单元变为)。early.service
ExecStartPre
active (running)
与服务不同,目标不会进入“启动”状态。相反,他们被“达成”了。early.target
让我们尝试使用和进行同样的操作late.service
,但late.service
需要一些时间才能开始:
$ systemctl --user cat early.target late.service
# /home/stew/.config/systemd/user/early.target
[Unit]
Wants=late.service
# /home/stew/.config/systemd/user/late.service
[Service]
ExecStartPre=sleep 2
ExecStart=sleep 5
$ systemctl --user start early.target
$ journalctl --user --since "2 minutes ago" --no-hostname
Mar 08 16:07:27 systemd[1064]: Starting late.service...
Mar 08 16:07:29 systemd[1064]: Started late.service.
Mar 08 16:07:29 systemd[1064]: Reached target early.target.
Run Code Online (Sandbox Code Playgroud)
early.target
我们看到“到达”需要2 秒。这意味着只有当目标的“Wants=”全部完成其“激活”阶段并进入“活动(运行)”状态时,目标才“达到”。
了解了这一点,我们现在可以理解为什么 aAfter=foo.target
与 a 混合WantedBy=foo.target
有点冲突了。 foo.target
正在等待我们在到达之前开始。同时,我们希望foo.target
在开始之前就与您取得联系。
归档时间: |
|
查看次数: |
9938 次 |
最近记录: |