systemd サービスが /etc/profile.d から環境変数を継承するようにする

systemd サービスが /etc/profile.d から環境変数を継承するようにする

systemd特定のユーザーでサービスを実行しています。

私は、サービスが、すべてのユーザーがスクリプト/エクスポートから継承する環境変数にアクセスできると誤って想定していました。/etc/profile.d

systemdユニット ファイル定義内の変数を手動でコピーせずにこれを実現する方法はありますか。

例えば、次のようなものがあります

$ cat /etc/profile.d/somexports

export VAR1=VALUE1
export VAR2=VALUE2

これをサービスに渡したりエクスポートしたりすることはできますかsystemd?

答え1

環境の原因としては、次のようなものが考えられます。

  1. whichを使用するとEnvironment=変数を設定できます
  2. whichを使用するとEnvironmentFile=ファイルから値を読み込むことができます
  3. which を使用するとPassEnvironment=、PID1 から渡される変数を定義できます。
  4. 静的構成(例$USER

は必要なことのように聞こえるかもしれませEnvironmentFile=/etc/profile.d/someexportsんが、そうではありません。 /etc/profile.d/*は多くの場合、シェルによってソース化され、シェルによって解析できます。 systemdはシェルに依存しないため、bash 構文に依存しません。 には、EnvironmentFileより厳密な改行で区切られた変数割り当てを含める必要があります。

systemdの設計では、ユニットやその環境を動的に変更することは推奨されていません。 このEnvironmentFile=オプションも圧力の結果として追加されただけであり、後に のsystemd開発者によって間違いであると判断されました。 この設計の一例は、 がどのバイナリが使用されるかには影響しないことです$PATH。 これにより、ユニットを定義するときに、外部の影響を気にせずにそのユニットがどのように実行されるかをすべて定義するため、物事がより決定論的になります。

したがって、簡単に答えると、「いいえ」です。ロードすることはできません/etc/profile.d/*systemd、これは意図的なものです。

しかし、おそらくあなたが知りたい答えは、「はい、ロードできます」です。シェルを介してアプリケーションを実行するだけです。

以下を変更することで実現できます:

ExecStart=/usr/bin/myservice

ExecStart=/usr/bin/bash -lc myservice

これにより、bashが親プロセスになり、/etc/profile.d/その環境が読み込まれ、子に転送されます。 への完全な絶対パスを指定していないことにも注意してください。myserviceこの場合、myserviceは に基づき$PATH、 は である場合もそうでない場合も/usr/bin/myserviceあります。これによりトラブルシューティングが困難になる可能性があることがわかります。これが、この方法を採用することの欠点です。

答え2

これは次のように対処されると思います

ExecStart=/bin/sh -lc /path/to/binary

この-lフラグは、シェルの呼び出しをログイン シェルにします。ログイン シェルのみがプロファイル スクリプトをソースとするため、これが必要です。

$ bash --help | grep -- -l
GNU bash, version 4.4.12(1)-release-(x86_64-pc-linux-gnu)
    --login

関連情報