存在しない場合は、いくつかの構成ファイルを生成し、存在する場合は読み取るソフトウェアを実行するサービスがあります。私が直面していた問題は、これらのファイルが時々破損してソフトウェアが起動せず、サービスが失敗することです。この場合、そのファイルを削除してサービスを再起動したいと思います。
次のように失敗した場合に実行する必要があるサービスを作成しようとします。
[Service]
ExecStart=/bin/run_program
OnFailure=software-fail.service
サービスはどこにありますか?
[Service]
ExecStart=/bin/rm /file/to/delete
ExecStop=systemctl --user start software.service
ところが問題はサービスが失敗しても始まらないという点だ。
~しようとする
systemctl --user enable software-fail.service
ただし、他のサービスと同様に、システムが起動するたびに起動します。
私の一時的な解決策は
ExecStopPost=/bin/rm /file/to/delete
しかし、これは欠陥が原因であるかどうかに関係なく、サービスが停止した場合は常にファイルを削除するため、満足のいく解決策ではありません。
失敗時の出力:
● software.service - Software
Loaded: loaded (/home/trippelganger/.config/systemd/user/software.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Fri 2018-05-04 09:05:26 CEST; 5s ago
Process: 1839 ExecStart=/bin/run_program (code=exited, status=1/FAILURE)
Main PID: 1839 (code=exited, status=1/FAILURE)
May 04 09:05:26 trippelganger systemd[595]: software.service: Main process exited, code=exited, status=1/FAILURE
May 04 09:05:26 trippelganger systemd[595]: software.service: Unit entered failed state.
May 04 09:05:26 trippelganger systemd[595]: software.service: Failed with result 'exit-code'.
systemctl --user status Software-fail.service の出力は次のとおりです。
● software-fail.service - Delete corrupt files
Loaded: loaded (/home/trippelganger/.config/systemd/user/software-fail.service; disabled; vendor preset: enabled)
Active: inactive (dead)
答え1
ノートExecStopPost=
:ここで代わりに使用したいかもしれませんがOnFailure=
(他の答えを参照)、OnFailure=
設定がうまくいかない理由を解決しようとします。
デバイスを起動できない問題は、デバイスが必要なOnFailure=
誤った部分にあるためです。[Unit]
[Service]
次のことを試すことができます。
# software.service
[Unit]
Description=Software
OnFailure=software-fail.service
[Service]
ExecStart=/bin/run_program
そして:
# software-fail.service
[Unit]
Description=Delete corrupt files
[Service]
ExecStart=/bin/rm /file/to/delete
ExecStop=/bin/systemctl --user start software.service
この設定で動作させることができます。
しかし、OnFailure=
プログラムが失敗した理由は実際にはわからず、ExecStop=
直接呼び出して他の起動をリンクするのはやや古いので、ここで使用するのは理想的ではありません。シャットダウンの/bin/systemctl start
回避策を使用して確認します。状態プログラムは絶対に優れています。ExecStopPost=
OnFailure=
inside を定義すると、[Service]
systemd (最小 Fedora 27 バージョン 234) は次のエラーを表示します。
software.service:6: Unknown lvalue 'OnFailure' in section 'Service'
ログにこの内容が表示されているかどうかはわかりません...
答え2
サービスが失敗したときにいくつかのクリーンアップを実行するには、次のものを使用できます。ExecStopPost=
、サービスが成功したかどうかに関係なく実行されます。
実行中のコードで、またはいずれかを使用してExecStopPost=
失敗条件を確認し、適切な処置を取ることができます。より$SERVICE_RESULT
$EXIT_CODE
$EXIT_STATUS
文書どの環境変数があなたに適しているかを確認するには、次の環境変数を確認してください。
Restart=on-failure
その後、失敗した場合はsystemdを使用してデバイスを再起動できます。
すべて合わせるとこんな姿になります。ファイルが破損するたびにステータス2で終了すると仮定するとrun_program
(上記のドキュメントの他のエラーシナリオに適用できることを願っています)、次のように動作します。
[Service]
ExecStart=/bin/run_program
ExecStopPost=/bin/sh -c 'if [ "$$EXIT_STATUS" = 2 ]; then rm /file/to/delete; fi'
Restart=on-failure
(ノート:シェルが変数を$$
表示してアクセスできるように、ダブルドル記号がsystemdにエスケープされます。$EXIT_STATUS
単一のドル記号を使用することも機能しますが、systemdは置き換えを実行し、シェルは言うとうまくいくよう[ "2" = 2 ]
です。そのうち、フルパスを通過する方がExecStopPost=
良いかもしれませんし、エラー状況から回復するために行われたアクションを記録するなど、スクリプトにコマンドを追加するのは簡単です。 )
これがあなたの特定の状況に合わせて正しく設定する方法についての十分なガイドラインであることを願っています。
答え3
注意が必要なのはsystemd
バージョンです。$EXIT_STATUS
2017年5月にリリースされたSystemdバージョン232には、利点と関連する価値が導入されました。
RHEL 7.xなどの一部のディストリビューション(入力時)はまだsystemdバージョン219を使用しています$EXIT_STATUS
。