Systemd 單元的 After= 指令未按預期工作
所以,我開始分解我的系統初始化並為我登錄後想要載入的東西創建一些服務文件。這是常見的東西,比如 polybar、dunst 和其他東西。事情確實有效,但我的 pywal 設置存在一些問題。我已經將依賴項分離到一個單獨的 .target 中,稱為
theme.target
[Unit] Description = Theme dependencies BindsTo = xsession.target Wants = pywal.service Wants = i3.service Wants = polybar.service Wants = dunst.service
我想要實現的是僅在 pywal.service 完全執行並完成啟動腳本的執行後才載入 i3(以及列表的其餘部分)。
在 .bin/pywal 我確實睡了 10 秒
pywal.服務
[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 秒不重啟?
編輯:根據評論修復了一個句子以在這種情況下更有意義
您對“成功執行”的理解與 systemd 的想法不匹配*。*對於諸如此類的服務,“類型”是“簡單”,這意味著:
如果設置為 simple(如果指定了 ExecStart= 但 Type= 和 BusName= 均未指定,則為預設值),服務管理器將認為該單元在主服務程序被分叉後立即啟動。
(我的重點)
這裡的細微區別是時間安排之一:systemd 認為 pywal 單元在啟動後立即啟動,而您希望後續單元等到它“已完成啟動腳本的執行”
%h/.bin/pywal
。結果,依賴項會在它們能夠啟動時立即啟動(根據 systemd),這意味著 i3 將在 pywal 啟動後很快啟動,並且 pywal 可以隨心所欲地休眠——它對i3的開始時間。
我相信這裡的正確答案是讓 pywal 成為 Type=Notify 並讓它在準備好時通知 systemd。有關 systemd-notify 的更多資訊,請參閱這些:
一種解決方法是使用ExecStartPre修改 i3 單元:
# ... [Service] ExecStartPre = /bin/sleep 10 ExecStart = /usr/bin/i3-msg restart # ...
…強制實際 i3 執行檔在執行前等待 10 秒。