Systemd - 在 ExecStopPost 中检测服务是否无错退出

Systemd - detect in ExecStopPost whether service exited without error

我有一个应用程序,在它正常完成并退出后不应重新启动。在此应用程序完成其业务后,我想关闭实例 (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

问题是当post停止运行s时我好像没法检测服务是否正常结束,状态是deactivating,只有do我知道它是否进入failed状态。

您的问题是 systemd 认为服务是 deactivating,直到 ExecPostStop 进程完成。入睡无济于事,因为它只会等待更长的时间。 ExecPostStop 的想法是清理服务可能留下的任何东西,如临时文件、UNIX 套接字等。服务尚未完成,并准备好再次启动,直到清理完成。所以如果你这样看,systemd 所做的事情确实有意义。

您应该做的是检查脚本中的 $SERVICE_RESULT$EXIT_CODE and/or $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.