Systemd は、別のサービスが開始されると、1 つのサービスを停止します。

Systemd は、別のサービスが開始されると、1 つのサービスを停止します。

たとえば、通常は互いに競合するいくつかのサービス(同じポートなど)があります。しかし、同時に実行する必要はありません。たとえば、サービスを開始すると、そのサービスが実行されていることをa確認して停止しますか?他のサービスが実行されていない場合は正常に起動します。しかし、そうであれば、他のサービスにコマンドを送信します。bcbstop

systemctl stop a.service現時点では、回避策としてwhileループを実行し、停止が返されるsystemctl status a.serviceまでgrepを実行し、systemctl stop c.servicewhileループを実行して停止がsystemctl status c.service返されるまでgrepする.shがあります。どちらも停止してから実行してから戻りますsystemctl start b.service。それから私はスタートアップとa.service同じファイルを作成しましたc.serviceが、私の考えでは、この回避策がやや混乱して正式なものであるかどうか疑問に思います。

答え1

~からsystemd.unit(5):

紛争=

スペースで区切られた単位名のリスト。否定的な要件依存関係を構成します。あるユニットが別のユニットに衝突=を設定した場合、前者を起動すると後者は停止し、その逆の場合も同様です。

この設定は、上記のWants =およびRequires =依存関係と同様の順序依存関係を意味しません。つまり、他のデバイスが起動する前に競合するデバイスが停止するようにするには、After= または Before= 依存関係を宣言する必要があります。ジョブの停止は常にジョブの開始前にソートされるため、2 つのソート依存関係のどちらが使用されるかは重要ではありません。以下の Before=/After= の説明をご覧ください。

デバイスBと競合するデバイスAがデバイスBと同時に起動するようにスケジュールされている場合、トランザクションは失敗するか(両方がトランザクションの必須部分である場合)、それを修正するために修正されます(1つまたは両方の操作が破損した場合)。取引の必須部分ではありません))。後者の場合、不要なタスクが除去された場合、またはその両方が不要な場合、競合するデバイスが起動し、競合するデバイスが停止します。

したがって、殺したいときにB始めるたびに追加するCだけです。A[Unit]A.service

[Unit]
Conflicts=B.service C.service

Conflict=3つのユニットをすべて組み合わせると、どのユニットを実行するかを選択できます。したがって、Aを起動するとB&Cが終了し、Bを起動するとA&Cが終了し、Cを起動するとA&Bが終了します。

デフォルトでは実行しようとしているように聞こえるB.serviceので、1つだけWantedBy=multi-user.target重要です。他の項目に追加しないでください(または有効にしないでください)。それ以外の場合は、起動時にすべての起動を試み、失敗するか、ランダムなエントリが引き続き実行されます。

B.service止めA.serviceたりしたらあなたも始めたいと思いますC.service。あなたが望んでいないよりもあなたが望むものについてもっと考えてみてください。 Systemdには、他のデバイスがシャットダウンしたときに1つのデバイスを起動する関係はありません。システム全体をシャットダウンするために、systemdは次のようにします。shutdown.targetすべてと衝突して崩れます。 Cがシャットダウンを停止し、シャットダウン中にBを開始すると想像してください。

関連情報