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. Environment=変数の設定に使用
  2. EnvironmentFile=ファイルから値をロードするには、それを使用します。
  3. これにより、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

関連情報