systemdを使用したArch Linuxシステム を使用しており、独自のサービスを作成しました。 /etc/systemd/system/myservice.service
の構成サービスは次のようになります。
[Unit]
Description=My Daemon
[Service]
ExecStart=/bin/myforegroundcmd
[Install]
WantedBy=multi-user.target
次に、/bin/myforegroundcmd
に環境変数を設定します。それ、どうやったら出来るの?
時代は変わり、ベストプラクティスも変わります。
(current これを行う最良の方法は、systemctl edit myservice
を実行することです。これにより、オーバーライドファイルが作成されます。既存のものを編集できます。
通常のインストールでは、これによりディレクトリ/etc/systemd/system/myservice.service.d
が作成され、そのディレクトリ内に名前が.conf
で終わるファイル(通常はoverride.conf
)が作成されます。このファイルに追加または上書きできます配布によって出荷されたユニットの任意の部分。
たとえば、ファイル/etc/systemd/system/myservice.service.d/myenv.conf
の場合:
[Service]
Environment="SECRET=pGNqduRFkB4K9C2vijOmUDa2kPtUhArN"
Environment="ANOTHER_SECRET=JP8YLOc2bsNlrGuD6LVTq7L36obpjzxd"
また、ディレクトリが存在し、空の場合、サービスは無効になります。ディレクトリに何かを配置するつもりがない場合は、それが存在しないことを確認してください。
参考までに、古い方法は:
推奨される方法 これを行うには、変数を含むファイル/etc/sysconfig/myservice
を作成し、それらをEnvironmentFile
でロードします。
詳細については、Fedoraのドキュメント systemdスクリプトの記述方法 を参照してください。
答えは、変数が定数である(つまり、ユーザーがユニットを取得することによって変更されることを想定していない)か、変数(ユーザーが設定したと想定される)であるかによって異なります。
ローカルユニットであるため、境界はかなりぼやけており、どちらの方法でも機能します。ただし、配布を開始して/usr/lib/systemd/system
になる場合は、これが重要になります。
インスタンスごとに値を変更する必要がない場合は、ユニットファイルに直接Environment=
として配置することをお勧めします。
[Unit]
Description=My Daemon
[Service]
Environment="FOO=bar baz"
ExecStart=/bin/myforegroundcmd
[Install]
WantedBy=multi-user.target
その利点は、変数がユニットと共に単一のファイルに保持されることです。したがって、ユニットファイルはシステム間を移動する方が簡単です。
ただし、sysadminが環境変数の値をローカルで変更することになっている場合、上記のソリューションはうまく機能しません。具体的には、ユニットファイルが更新されるたびに新しい値を設定する必要があります。
この場合、追加のファイルが使用されます。方法—通常は配布ポリシーによって異なります。
特に興味深い解決策の1つは、/etc/systemd/system/myservice.service.d
ディレクトリを使用することです。他のソリューションとは異なり、このディレクトリはsystemd自体でサポートされているため、ディストリビューション固有のパスはありません。
この場合、/etc/systemd/system/myservice.service.d/local.conf
のようなファイルを配置して、ユニットファイルの不足している部分を追加します。
[Service]
Environment="FOO=bar baz"
その後、systemdはサービスの開始時に2つのファイルをマージします(どちらかを変更した後はsystemctl daemon-reload
に注意してください)。また、このパスはsystemdによって直接使用されるため、EnvironmentFile=
を使用しないでください。
影響を受けるシステムの一部でのみ値が変更されることになっている場合は、両方のソリューションを組み合わせて、ユニットに直接デフォルトを指定し、他のファイルにローカルオーバーライドを指定できます。
http://0pointer.de/public/systemd-man/systemd.exec.html#Environment= -2つのオプションがあります(1つはMichaelがすでにポイントしています):
Environment=
そして
EnvironmentFile=
Michael および Michał による回答は役に立ち、systemdサービスの環境変数を設定する方法についての元の質問に回答します。ただし、環境変数の 一般的な使用 の1つは、パスワードなどの機密データを、アプリケーションのコードで誤ってソース管理にコミットされない場所に構成することです。
そのため、サービスに環境変数を渡したい場合は、しないでくださいユニット構成ファイルでEnvironment=
を使用します。 EnvironmentFile=
を使用して、サービスアカウント(およびrootアクセス権を持つユーザー)のみが読み取り可能な別の構成ファイルを指定します。
ユニット構成ファイルの詳細は、次のコマンドですべてのユーザーに表示されます。
systemctl show my_service
私は/etc/my_service/my_service.conf
に構成ファイルを置き、そこに私の秘密を置きます:
MY_SECRET=correcthorsebatterystaple
次に、サービスユニットファイルでEnvironmentFile=
を使用しました。
[Unit]
Description=my_service
[Service]
ExecStart=/usr/bin/python /path/to/my_service.py
EnvironmentFile=/etc/my_service/my_service.conf
User=myservice
[Install]
WantedBy=multi-user.target
ps auxe
がこれらの環境変数を表示できないこと、および他のユーザーが/proc/*/environ
にアクセスできないことを確認しました。もちろん、あなた自身のシステムをチェックしてください。
マイケルは1つのクリーンなソリューションを提供しましたが、スクリプトから更新されたenv変数を取得したいと思いました。 systemdユニットファイルでは、残念ながらbashコマンドを実行できません。さいわい、ExecStart内でbashをトリガーできます。
http://www.dsm.fordham.edu/cgi-bin/man-cgi.pl?topic=systemd.service&sect=5
この設定はシェルコマンドラインを直接サポートしないことに注意してください。シェルコマンドラインを使用する場合は、何らかのシェル実装に明示的に渡す必要があります。
この場合の例は次のとおりです。
[Service]
ExecStart=/bin/bash -c "ENV=`script`; /bin/myforegroundcmd"