使 systemd 服務從 /etc/profile.d 繼承環境變數
我有一個
systemd
在特定使用者下執行的服務。我錯誤地假設該服務可以訪問所有使用者從腳本/導出下繼承的環境變數
/etc/profile.d
有沒有一種方法可以實現這一點,而不必手動複製
systemd
單元文件定義中的變數。例如,我有以下
$ cat /etc/profile.d/somexports export VAR1=VALUE1 export VAR2=VALUE2
這可以傳遞/導出到
systemd
服務嗎?
有幾種可能的環境來源:
- 使用
Environment=
which 可以設置變數- 使用
EnvironmentFile=
which 可以從文件中載入值- 使用
PassEnvironment=
which 可以定義應該從 PID1 傳遞的變數。- 靜態配置(例如
$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
。您可以看到這可能會使故障排除變得更加困難,這就是走這條路線的缺點。