使 systemd 使用者服務依賴於系統目標
我有這樣的使用者服務
~/.config/systemd/user/example.service
:[Unit] Description=Example service After=network.target [Service] ExecStart=/bin/bash -c 'host google.com > /var/tmp/example' [Install] WantedBy=default.target
當然,我試圖控制的實際服務實際上做了一些有用的事情並訪問了網路;這只是一個簡化的例子。
該服務通過它創建指向
systemctl --user enable example.service
的符號連結啟用。~/.config/systemd/user/default.target.wants/example.service``~/.config/systemd/user/example.service
使用此設置,並按照Arch Wiki
systemd
中的說明啟用使用者會話,該服務在啟動時以我的使用者身份啟動。但是,它實際上並沒有在網路建立後啟動;相反,它似乎立即開始,因為包含:/var/tmp/example
;; connection timed out; no servers could be reached
(而且我試圖控制的實際服務也無法訪問網路,並且由於類似的名稱查找錯誤而失敗)
這意味著該服務實際上並沒有在
network.target
. 如何讓它network.target
在執行前等待?
忘記
network.target
.man systemd.special
說:network.target systemd automatically adds dependencies of type After for this target unit to all SysV init script service units with an LSB header referring to the $network facility.
因此,這個目標主要是 SysV 初始化腳本的兼容性黑客。
假設您的網路連接由 NetworkManager 處理,您當然可以正確地依賴此目標,因為
NetworkManager.service
定義了Before=network.target
. 但這僅表示 NetworkManager 已經啟動,並不表示網路連接實際上已經建立。這可能需要一段時間(dhcp 往返、wifi 握手等),這完全是 NetworkManager 的工作。至少在我的系統(F18)上有一個名為NetworkManager-wait-online
. 它使用nm-online
實用程序進行阻塞,直到建立了活動連接。在您的單元定義中嘗試Require, Before
這樣做或單獨使用該工具。