![After= systemd 单元的指令未按预期工作](https://linux22.com/image/203911/After%3D%20systemd%20%E5%8D%95%E5%85%83%E7%9A%84%E6%8C%87%E4%BB%A4%E6%9C%AA%E6%8C%89%E9%A2%84%E6%9C%9F%E5%B7%A5%E4%BD%9C.png)
因此,我开始分解系统初始化,并为登录后要加载的内容创建一些服务文件。这是常见的东西,比如 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 秒。