After= systemd 单元的指令未按预期工作

After= systemd 单元的指令未按预期工作

因此,我开始分解系统初始化,并为登录后要加载的内容创建一些服务文件。这是常见的东西,比如 Polybar、Dunst 和其他东西。一切确实有效,但我的 pywal 设置存在一些问题。我已将依赖项分离到一个名为的单独的 .target 中

主题.目标

[Unit]
Description = Theme dependencies
BindsTo = xsession.target
Wants = pywal.service
Wants = i3.service
Wants = polybar.service
Wants = dunst.service

我想要实现的是让 i3 (以及列表的其余部分)仅在 pywal.service 完全运行并完成启动脚本的执行后加载。

在 .bin/pywal 中我确实睡了 10 秒

pywal.service

[Unit]
Description = Run pywal service responsible for color schemes
PartOf = theme.target

[Service]
ExecStart = %h/.bin/pywal

[Install]
WantedBy = theme.target

i3服务

[Unit]
Description = A tiling window manager
PartOf = theme.target
After = pywal.service
Requires = pywal.service

[Service]
ExecStart = /usr/bin/i3-msg restart

[Install]
WantedBy = theme.target

我可能对“成功运行”的实际含义感到困惑,但我注意到 i3 服务一旦运行就会立即重新启动

systemctl --user restart theme.target

然后我只是观察所有 3 个服务/目标的状态,并看到 i3 已与 pywal.service 同时重新启动。

那么基本上我在这里错过了什么以及为什么 i3 在 pywal 后 10 秒不重新启动?

编辑:根据评论修正了一个句子,以便在这种情况下更有意义

答案1

那里您对“成功运行”的理解与 systemd 的想法不匹配。对于此类服务,“类型”是“简单”, 意思是:

如果设置为 simple(如果指定了 ExecStart= 但 Type= 和 BusName= 均未指定,则为默认值),服务管理器将认为该单元已启动主要服务进程被分叉后立即。

(我的重点)

这里的微妙区别在于时间:systemd 认为 pywal 单元一旦%h/.bin/pywal启动就启动发起而您希望后续单元等待,直到“已完成启动脚本的执行”。

因此,依赖项会在有能力时立即启动(根据系统),这意味着 i3 将在 pywal 启动后不久启动,并且 pywal 可以随心所欲地休眠——它对 i3 的启动时间没有进一步的影响。

我相信这里正确的答案是让 pywal 为 Type=Notify 并让它在准备就绪时通知 systemd。有关 systemd-notify 的更多信息,请参阅以下内容:

解决方法可能是修改 i3 单元执行开始前

# ...
[Service]
ExecStartPre = /bin/sleep 10
ExecStart = /usr/bin/i3-msg restart
# ...

...强制实际的 i3 可执行文件在运行前等待 10 秒。

相关内容