Systemd

使 systemd 服務從 /etc/profile.d 繼承環境變數

  • November 1, 2021

我有一個systemd在特定使用者下執行的服務。

我錯誤地假設該服務可以訪問所有使用者從腳本/導出下繼承的環境變數/etc/profile.d

有沒有一種方法可以實現這一點,而不必手動複製systemd單元文件定義中的變數。

例如,我有以下

$ cat /etc/profile.d/somexports

export VAR1=VALUE1
export VAR2=VALUE2

這可以傳遞/導出到systemd服務嗎?

有幾種可能的環境來源:

  1. 使用Environment=which 可以設置變數
  2. 使用EnvironmentFile=which 可以從文件中載入值
  3. 使用PassEnvironment=which 可以定義應該從 PID1 傳遞的變數。
  4. 靜態配置(例如$USER

這聽起來像是EnvironmentFile=/etc/profile.d/someexports你想要的,但事實並非如此。 /etc/profile.d/*通常由您的 shell 提供,並且可以由您的 shell 解析。 systemd與 shell 無關,因此它不會依賴 bash 語法。EnvironmentFile應該包含必須更嚴格的換行符分隔的變數賦值。

systemd的設計不鼓勵動態變化的單位或其環境。甚至這個EnvironmentFile=選項也是迫於壓力才添加的,後來被systemd’s 的開發者認為是一個錯誤。這種設計的一個例子是$PATH不影響使用哪些二進製文件。這使事情更具確定性,因為當您定義一個單元時,您正在定義有關該單元應如何執行的所有內容,而無需擔心外部影響。

所以簡短的回答是:不,你不能載入/etc/profile.d/*systemd這是故意的。

但您可能想要的答案是:是的,您可以載入它。您只需要通過 shell 執行您的應用程序。

您可以通過更改來做到這一點:

ExecStart=/usr/bin/myservice

ExecStart=/usr/bin/bash -c myservice

這將導致bash成為父程序,它將/etc/profile.d/將該環境載入並轉發給它的子程序。另請注意,我沒有指定完整的絕對路徑myservice。在這種情況下,myservice將基於$PATH並且可能是也可能不是/usr/bin/myservice。您可以看到這可能會使故障排除變得更加困難,這就是走這條路線的缺點。

引用自:https://unix.stackexchange.com/questions/675521