システムワンショットは一度だけ実行する必要があります。

システムワンショットは一度だけ実行する必要があります。

環境ファイルを生成する必要があるいくつかのシステムサービスがあります。この環境ファイルを生成するシェルスクリプトがありますが、環境ファイルが必要なため今後Exec... コマンドを実行するには、ExecStartPre=generate_env_file.sh を使用できません。そのため、スクリプトを一度実行するために別のサービス(generate_env_file.service)を設定しました。

[Service]
Type=oneshot
ExecStartPre=/usr/bin/touch /path/to/config.ini
ExecStart=/path/to/generate_env_file.sh

以下を含む他のサービスファイルがいくつかあります。

[Unit]
Requires=generate_env_file.service
After=generate_env_file.service

2つ以上の依存サービス(generate_env_file.serviceが必要)が並列に実行されないようにし、並列に実行される2つのgenerate_env_file.servicesを生成する方法は?

RemainAfterExit = trueまたはStartLimitIntervalSec =とStartLimitBurst =を使用して一度に1つのコピーのみを実行することを検討しましたが、これを行う最善の方法はわかりません。

答え1

RemainAfterExit=true行く道です。この場合、Systemd はサービスを開始し、Systemd はサービスが開始されアクティブであると考えます。ただし、これには実行されたユースケースは含まれませんsystemctl restart generate_env_file.service。この場合、systemd はサービスを再実行します。この問題を解決するには、実行中のファイルシステムにタグファイルを作成してExecStartPost=追加できます。ConditionPathExists=ディレクティブはファイルが存在することを確認します。

答え2

ConditionFirstBootまた興味深いかもしれません:

ブールパラメータを使用します。この条件は、システムが初めて起動するかどうかによってデバイスの状態を決定するために使用できます。これは、おおよそ/etc/ブートを開始したときにシステムがいっぱいにならないことを意味します(詳細については、最初のブートセマンティクスを参照)。 マシンID(5))。管理者が開始ステップを完了した後、最初の開始は完了と見なされます(この条件はfalseと評価されます)。

/etc/この条件は、工場リセット後の最初の起動時、または新しいシステムインスタンスの最初の起動時に設定するために使用できます。

堅牢性のために、ユニットはConditionFirstBoot=yes最初に自分自身を命令し、first-boot-complete.targetこの手動目標を引き付ける必要がありますWants=。これにより、最初の起動が中断された場合は、次のシステム起動中にそのデバイスが再起動されます。

このオプションがカーネルコマンドラインで指定されている場合systemd.condition-first-boot=(ブール値を使用)、この条件付き検証結果は無視され、/etc/machine-id 存在確認よりも優先されます。

答え3

generate_env_file.sh起動後すぐにロックファイルがあることを確認するように更新されました。ロックファイルがある場合はすぐに終了します。

ロックファイルがない場合は、今すぐロックファイルをタッチしてプロファイルを作成し、ロックファイルを削除してください。

つまり、systemd設定で説明する状況を処理する基本的な方法がないと思うので、ロックファイルを使用してください。

@shellterが指摘したように、Unixサイトはsystemd今後の質問のためのより良いサイトです。

関連情報