Systemd - 在ExecStopPost中检测服务是否退出而没有错误

时间:2016-03-28 15:15:00

标签: linux systemd

我有一个应用程序,在它完成并正常退出后不应该重新启动。在此应用程序完成其业务之后,我想关闭实例(ec2)。我正在考虑使用带有选项

的systemd单元文件来执行此操作
Restart=on-failure
ExecStopPost=/path/to/script.sh

应该在ExecStopPost上运行的脚本:

#!/usr/bin/env bash

# sleep 1; adding sleep didn't help

# this always comes out deactivating
service_status=$(systemctl is-failed app-importer) 

# could also do the other way round and check for failed
if [ $service_status = "inactive" ] 
then
  echo "Service exited normally: $service_status . Shutting down..."
  #shutdown -t 5
else
  echo "Service did not exit normally - $service_status"
fi
exit 0

问题是,当停止后运行时,我似乎无法检测到服务是否正常结束,状态是deactivating,只有在我知道它是否进入failed之后国家与否。

1 个答案:

答案 0 :(得分:4)

您的问题是,在deactivating进程完成之前,systemd会将服务视为ExecPostStop。睡一觉没有帮助,因为它只会等待更长的时间。 ExecPostStop的想法是清除服务可能留下的所有内容,例如临时文件,UNIX套接字等。该服务尚未完成,并准备再次启动,直到清除完成。因此,如果您以这种方式看,systemd所做的事情确实很有意义。

您应该做的是检查脚本中的$SERVICE_RESULT$EXIT_CODE和/或$EXIT_STATUS,这将告诉您服务如何停止。示例:

#!/bin/sh
echo running exec post script | logger
systemctl is-failed foobar.service | logger
echo $SERVICE_RESULT, $EXIT_CODE and $EXIT_STATUS | logger

允许服务运行到完成时:

Sep 17 05:58:14  systemd[1]: Started foobar.
Sep 17 05:58:17  root[1663]: foobar service will now exit
Sep 17 05:58:17  root[1669]: running exec post script
Sep 17 05:58:17  root[1671]: deactivating
Sep 17 05:58:17  root[1673]: success, exited and 0

当服务在完成之前停止时:

Sep 17 05:57:22  systemd[1]: Started foobar.
Sep 17 05:57:24  systemd[1]: Stopping foobar...
Sep 17 05:57:24  root[1643]: running exec post script
Sep 17 05:57:24  root[1645]: deactivating
Sep 17 05:57:24  root[1647]: success, killed and TERM
Sep 17 05:57:24  systemd[1]: Stopped foobar.