After=multi-user.target 和其他不在 systemd 服务中工作的

run*_*ace 4 systemd services

我有一个工作的服务,只有在运行之后才工作,因为它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)

在此输入图像描述

RON建议的注意事项

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)

结果是:

在此输入图像描述

Ste*_*art 7

定义WantedBy=multi-user.targetAfter=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=为了清楚起见,我会放弃依赖性。


/关系确实有效,下面是两个服务在没有/BeforeAfter情况下进行交互的示例:BeforeAfter

$ 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.serviceExecStartPreactive (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在开始之前就与您取得联系。