web-dev-qa-db-ja.com

systemdサービスの戻りコードを処理するスクリプト

Systemctlコマンドを使用して開始または停止できるsystemdサービスを書いています。

ただし、このプログラムはいくつかの戻りコードで戻ることもできるので、それらの戻りコードを処理したいと思います。

たとえば、サービスがsystemctl stop <service>で停止された場合は、何もしません。しかし、それがsystemctlによって強制終了されず、それ自体によって返されなかった場合は、ポストスクリプトを実行して、戻りコードを取得し、その値に応じてアクションを実行できます。


@NarūnasKの回答の後で変更
systemdバージョン> = v232の場合、@NarūnasK回答で問題ありません


しかし、良いsystemdバージョンがない場合、どうすればそれができますか?

私はのようなことをすることについても

ExecStart=/bin/sh -c '<service> -C /etc/<service_conf_file>; [ $? -eq 1 ] && { <action> }'
1
Arkaik

ExecStopPost = は必要な処理を実行する必要があります。

サービスの停止後に実行される追加のコマンド。これには、ExecStop =で構成されたコマンドが使用された場合、サービスにExecStop =が定義されていない場合、またはサービスが予期せず終了した場合が含まれます。この引数は、ExecStart =で説明したのと同じスキームに従って、複数のコマンドラインを取ります。これらの設定の使用はオプションです。指定子と環境変数の置換がサポートされています。 – ExecStop =とは異なり–この設定で指定されたコマンドは、サービスが正しく起動できず、再びシャットダウンされたときに呼び出されます。

サービスの正常な起動に失敗した場合でも実行されるクリーンアップ操作には、この設定を使用することをお勧めします。この設定で構成されたコマンドは、サービスが途中で起動に失敗し、不完全に初期化されたデータが残った場合でも動作できる必要があります。この設定で指定されたコマンドが実行されるとき、サービスのプロセスはすでに終了しているので、それらはそれらと通信しようとすべきではありません。

この設定で構成されるすべてのコマンドは、$ SERVICE_RESULT、$ EXIT_CODE、および$ EXIT_STATUS環境変数に設定されているメインプロセスの終了コードとステータスとともに、サービスの結果コードで呼び出されることに注意してください。systemd.execを参照してください(5)詳細については。

スクリプトで、$EXIT_CODEまたは$EXIT_STATUS環境変数を読み取り、適切なアクションを実行できます。

[〜#〜]編集[〜#〜]

systemd < 232では、次の回避策を使用できます。

sample_script

#! /bin/bash --

sleep 5

## Non standard exit code
exit 255

exit_handler

#! /bin/bash --

CODE="${1:-N/A}"

echo CODE: $CODE
echo SERVICE_RESULT: $SERVICE_RESULT
echo EXIT_CODE: $EXIT_CODE
echo EXIT_STATUS: $EXIT_STATUS

sample_script.service

# systemctl cat sample_script.service 
# /etc/systemd/system/sample_script.service
[Unit]
Description=My service
After=network.target rsyslog.service

[Service]
Type=simple
Restart=never
ExecStart=/bin/bash -c '/tmp/sample_script || /tmp/exit_handler $?'
ExecStopPost=/tmp/exit_handler

[Install]
WantedBy=multi-user.target

sample_script.serviceのステータス:

# systemctl status sample_script.service 
● sample_script.service - My service
   Loaded: loaded (/etc/systemd/system/sample_script.service; enabled)
   Active: inactive (dead) since Thu 2017-12-14 12:29:16 GMT; 7s ago
  Process: 16511 ExecStopPost=/tmp/exit_handler (code=exited, status=0/SUCCESS)
  Process: 16505 ExecStart=/bin/bash -c /tmp/sample_script || /tmp/exit_handler $? (code=exited, status=0/SUCCESS)
 Main PID: 16505 (code=exited, status=0/SUCCESS)

Dec 14 12:29:11 build-local systemd[1]: Started My service.
Dec 14 12:29:16 build-local bash[16505]: CODE: 255
Dec 14 12:29:16 build-local bash[16505]: SERVICE_RESULT:
Dec 14 12:29:16 build-local bash[16505]: EXIT_CODE:
Dec 14 12:29:16 build-local bash[16505]: EXIT_STATUS:
Dec 14 12:29:16 build-local exit_handler[16511]: CODE: N/A
Dec 14 12:29:16 build-local exit_handler[16511]: SERVICE_RESULT:
Dec 14 12:29:16 build-local exit_handler[16511]: EXIT_CODE:
Dec 14 12:29:16 build-local exit_handler[16511]: EXIT_STATUS:

exit_handlerが2回呼び出されていることがわかります。最初にbashから終了コードが提供され、次にExecStopPost=スクリプトとして終了コードの位置引数が提供されなかったため、N/Aが出力されました。

2
NarūnasK