Bash 腳本作為 linux-service 不會運行,但從終端執行完美

Bash 腳本作為 linux-service 不會運行,但從終端執行完美

我有自訂腳本來安裝Google驅動器。
該腳本的一部分是以下程式碼:

if [ ! "$(which google-drive-ocamlfuse)" ]
then
    echo "Install google-drive-ocamlfuse first!"
    exit 1
fi

從終端執行,效果非常好。
所以,我將其配置為服務:

[Unit]
Description=Mount and umount google drives

[Service]
User=<usernamehere>
Type=oneshot
RemainAfterExit=true
ExecStart=/home/<usernamehere>/mybscripts/gdrivemounter.sh -m
ExecStop=/home/<usernamehere>/mybscripts/gdrivemounter.sh -u
Environment="DISPLAY=:0"
Environment="XAUTHORITY=/home/<usernamehere>/.Xauthority"

[Install]
WantedBy=graphical.target

不幸的是,我看到退出代碼:“首先安裝 google-drive-ocamlfuse!”當我檢查服務狀態。

命令哪個 google-drive-ocamlfuse在使用者和 root 下給了我有效的路徑:

$ which google-drive-ocamlfuse
/home/<usernamehere>/.opam/default/bin/google-drive-ocamlfuse

哪裡有問題?

答案1

問題是,當腳本作為服務運行時,它不會以“您”的身份運行:它沒有您的環境。具體來說,它沒有你的PATH變數。

新增/home/<usernamehere>/.opam/default/bin到腳本中的 PATH 中,或簡單地硬編碼該程式的完整路徑。

答案2

最可能的原因是包含的目錄google-drive-ocamlfuse在您的登入 shell 中PATH,但不在.PATHsystemd

只需在腳本的開頭添加這樣一行:

PATH=$PATH:/path/to/google-drive-ocamlfuse

答案3

謝謝大家的解決方案。每一個對我來說都很重要並且很有幫助——我再次學到了一些新東西。最後我決定從 deb 安裝 google-drive-ocamlfuse,而不是透過 opam。最好將 gdo 安裝在所有使用者可用的路徑中。因此,不需要額外配置 $PATH。

答案4

筆記:我「按原樣」保留了這個答案,但唯一相關的部分是如何透過服務文件設定環境,而不是直接在腳本中設定環境。腳本運行完成後,在腳本中設定新的 $PATH 將不會保留。

參考其他答案,請不要$PATH透過編輯腳本來污染您的腳本,事實上,如果由正確的使用者執行它就可以工作。如果必須直接在腳本中編輯它,請透過恢復原始$PATH.

我認為問題在於 /etc/profile 不由 systemd 服務處理,因此無論出於何種原因它都無法存取(或更新的 $PATH)所需的可執行檔。

要測試這一點,您可以在錯誤區塊中回顯 $PATH,如果缺少,則將其直接新增至 systemd 服務檔案中的環境變數:

[Service]
Environment=PATH=/home/someUser/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

這樣,僅在腳本運行時更新腳本的路徑,而不會為可能不希望修改它的使用者修改它。

相關內容