他のサービスが「完了」した後にシステムサービスを開始する方法は?

他のサービスが「完了」した後にシステムサービスを開始する方法は?

私は常にサービスAに関連するプログラムがサービスBの前に完了するように実行する必要がある状況に直面しています。 「以降」では問題は解決しません。後で言う

最も重要なのは、サービスデバイスの場合、設定された起動コマンドがすべて呼び出され、失敗した場合、または成功した起動を報告した場合、Before = / After =の目的に応じて起動が完了したと見なされることです。 」、ただし、これは基本プロセスが正常に完了したことを意味するわけではありません。

私の考えには、機能に目立つ穴があるようです。サービスBがサービスAの正常な完了に依存している場合、サービスBをどのように起動しますか?

答え1

この回答私の質問にほとんど明確に答えましたが、関連する説明を省略しましたType=oneshot。以下は関連テキストですsystemd.service ドキュメント

oneshotは単に機能しますが、サービスマネージャは基本プロセスが終了した後にデバイスを考慮します。次に、後続のデバイスを起動します。

したがって、ワンタイムサービスを使用して決定的なソートを実行できます。

答え2

これはquoteをRequires=使用するときによく使用されるユニークなソリューションです。After=man systemd.unit

必要=

Wants=に似ていますが、より強力な需要依存関係を宣言します。このタイプの依存関係は、ユニットファイルに付属の.requires /ディレクトリにシンボリックリンクを追加することによっても構成できます。

このデバイスがアクティブになると、リストされたデバイスもアクティブになります。他のデバイスのいずれかがアクティブではなく、注文の依存関係After =が失敗したデバイスに設定されている場合、そのデバイスは起動しません。また、After =を指定するかどうかにかかわらず、他のデバイスの1つが明示的に停止(または再起動)されると、このデバイスは停止(または再起動)されます。

After=依存するデバイスに基づいてデバイスが起動するタイミングを指定し、Requires=他のデバイスが正常に起動するタイミングを定義します。

答え3

ターゲットの問題は、閉じることを妨げることです。だから答えを見つけるのはとても難しいです。特権が上昇すると、shutdown.targetサービスは停止しますが、これにより後続のサービスがトリガーされます。


最初の仕事が短期パフォーマンスだった場合は、1つのサービスにまとめることを検討してください。Type=simpleと実行ExecStartPre=。システムは、最初のジョブが完了するまで保留され、最初のジョブが成功activatingした場合にのみ2番目のジョブを実行します。このスタイルは、最初のタスクを2番目のタスクに設定する必要がある場合に便利です。

[Service]
ExecStartPre=/path/to/firstjob
ExecStart=/path/to/secondjob

[Install]
WantedBy=multi-user.target

2番目のジョブも短期実行の場合は、以下を使用してください。Type=oneshot。この場合、両方が機能します。ExecStart=

[Service]
Type=oneshot
ExecStart=/path/to/firstjob
ExecStart=/path/to/secondjob

[Install]
WantedBy=multi-user.target

最初のジョブは短期実行ではありませんが、2番目のジョブは短期実行の場合は実行を検討してください。ExecStopPost=。ただし、このコマンドは成功したり失敗したりする可能性があるので注意してくださいExecStart=。最初のジョブが成功したかどうかを確認して、2 番目のジョブをスクリプトにラップして条件付きで実行できます。 $SERVICE_RESULT$EXIT_CODEそして$EXIT_STATUS。この例は、2番目のジョブがクリーンアップジョブの場合に特に便利です。

[Service]
ExecStart=/path/to/firstjob
ExecStopPost=/bin/bash -c "[ $SERVICE_RESULT = success ] && /path/to/secondjob"

[Install]
WantedBy=multi-user.target

両方のタスクを実行するのに時間がかかる場合は、もう少し創造性を発揮する必要があります。あなたができることの1つはトリガーを設定することです。*.path単位。これで姉妹サービスが実行されます。PathChanged=触れた。パスには一意でプレフィックスが付いたものを使用します。%t指定子このファイルを次の場所に置きます/run

# A.service
[Service]
ExecStart=/path/to/firstjob
ExecStopPost=/bin/bash -c "[ $SERVICE_RESULT = success ] && touch %t/B.trigger"

[Install]
WantedBy=multi-user.target

# B.path
[Path]
PathChanged=%t/B.trigger
Service=B.service

[Install]
WantedBy=multi-user.target

# B.service
[Service]
ExecStart=/path/to/secondjob

次のデバイスがトリガされる前にパスが停止するため、シャットダウンを妨げません。

関連情報