システム単位ファイルに動的「環境」変数を指定する方法は?

システム単位ファイルに動的「環境」変数を指定する方法は?

これは$(ls -d...)システム単位ファイルでは機能しません。

[Service]
Type=forking
Environment="ORACLE_HOME=$(ls -d /usr/lib/oracle/*/client64 | sort -rV | head -n1)"
Environment="TNS_ADMIN=$(ls -d /usr/lib/oracle/*/client64/lib/network/admin | sort -rV | head -n1)"

更新を簡素化するために、Oracleクライアントのバージョン(現在19.19)をハードコードすることを避けたいと思います。新しいOracleクライアントをインストールするときは、システム単位のファイルを変更したくありません。

どうすればいいですか?重要な場合はRHEL9を使用しています。

答え1

最も一般的な方法:

  • 使用EnvironmentFile=たとえば、ExecStartPre =を介して単純なスクリプトを呼び出して動的に生成されます。現在のシステムバージョンは、各実行前にEnvironmentFileを再読み込みして機能させるようにします。 (/runは一時ファイルを保存するのに最適な場所です。)

    スクリプトはこれらの行を作成するだけで済みます。これは最も簡単な方法ですKEY="value"

  • システムを使う発電機構成が(再)ロードされるたびに、/ run / systemdにユニットファイルを動的に作成します。ジェネレータは、ローカルファイルシステムへのアクセスに制限されている限り、シェルスクリプトにすることができます。

    ジェネレータは/etc/systemd/system-generators/起動するたびに、「systemctl daemon-reload」ごとに実行され、出力パスになるようにできます$1。ジェネレータは実際にデバイスが起動する前に実行されるため、ネットワークや他のものも起動することは期待できません。戻る。

    これは、環境だけでなくWorkingDirectory =などの他の要素まで、すべての単位オプションを動的に指定できるため、最も柔軟なアプローチです。 (ジェネレータは生成する必要はありません。みんなユニット作成したり、同様の方法で既存のユニットを拡張したりできます$1/oracle.service.d/environ.conf。 )

他の方法:

  • インスタンス化されたサービスユニットの使用[email protected]%iバージョンを埋めるために使用されます。それでも「oracle@old」を無効にして「oracle@new」を有効にする必要がありますが、これによりテキストエディタを開く時間が節約されます。 (また、正しいデバイスを起動して以前のバージョンにすばやくロールバックするのも簡単です。)考えるAlias=oracle.serviceインスタンスを有効にすると、自動的に短い名前にマッピングされるようにすることができます。

  • ラッパーシェルスクリプトを使用して変数を設定し、実際execのプログラムを保存します。はい、これはexec重要です。 (また、SyslogIdentifier =を使用すると、Journalctl出力にスクリプト名が表示されるのを防ぐことができます。)ラッパースクリプトは一般的にはお勧めできませんが、これは通常.serviceで簡単に実行できる操作を実行するためですが、100%いいえ。ここで。

systemctl set-environmentグローバルなので避けてください。変数を使用できます。みんな望んでいなくても、その時点からサービスが始まります。

関連情報