如何判断 systemd 运行的服务是否被终止/终止与正常退出?

如何判断 systemd 运行的服务是否被终止/终止与正常退出?
$ systemd-run sleep 1000
Running as unit: run-u635.service

如果我终止睡眠进程,或者即使我使用以下命令正确终止服务:

$ systemctl kill run-u635.service

我找不到该单元的任何属性来告诉我该进程被终止还是正常退出。例如。

$ systemctl show --property=ExecMainStatus run-u635.service
ExecMainStatus=0

如何区分正常退出的服务与被终止或崩溃的服务之间的区别?

答案1

如果您将服务运行为--service-type=oneshot( Type=oneshot),则退出SIGTERM将被视为失败。

对于像这样运行 shell 命令或 shell 脚本的服务来说,这实际上是常见的类型。 (与“守护进程”相反,“守护进程”通常“永远”运行,或者至少直到系统关闭为止)。当命令运行时,服务将显示为“正在启动”,而不是显示为“已启动”。如果使用--remain-after-exit( RemainAfterExit=yes),它将显示为started命令完成的时间。否则,stopped当命令完成时才会考虑它。您正在创建一个“瞬态”单元,因此当它停止时它会消失。

您很高兴 systemd-run 没有等待您的命令完成。 (我注意到,如果您使用了--wait,它会显示该命令以 退出SIGKILL)。在这种情况下,您可以使用如下命令:

systemd-run --service-type=oneshot --no-block sleep 1000

如果出现故障,它将显示在日志消息中。您可以使用journalctl查看它们。例如:

journalctl -b -u run-u635.service

如果您想在脚本中使用这种方法,它似乎不如您希望的方法那么好。您可能可以使用更好的功能组合;我认为这取决于更多地了解你想要实现的目标。

如果您使用的是用户单元 ( ),那么我会担心以前的登录会话中systemd-run --user ...可能存在其他实例。run-u635.service


这里的文档似乎不完整,至少在我的系统上是这样。中的文档man systemd.service似乎没有提到任何更改 的行为的可能性SIGTERM。我特别注意到 的定义SuccessExitStatus=没有提到这种可能性。

一般来说,systemd 不假设服务捕获 SIGTERM。某些服务在被请求终止时可能不需要执行任何操作。因此,通常存在的服务WTERMSIG() == SIGTERM不会被记录为异常退出。 (实际上,历史地systemd 文档说,用 SIGTERM 杀死的服务应该确保它以 退出WTERMSIG() == SIGTERM,即使它做过捕获信号)。

这听起来可能令人惊讶。请记住,Unix 和 Linux 已经使用了几十年没有任何服务监督。由于没有监控服务的退出状态,所以几乎可以肯定有一些服务在SIGTERM正常停止时仍然存在。

服务退出后,状态不可用:Unit run-u635.service could not be found.

正确的。事实是systemctl show 出现了在这种情况下工作,只是一个多么令人困惑的例子systemctl show:-(。当您尝试查询实际上不存在的服务的任何属性(甚至是目前尚未加载的服务)时,有没有错误消息,您只会看到默认/空属性值,除了属性LoadState- 这是它给您的唯一线索。

$ systemctl show --property=LoadState run-u635.service
LoadState=not-found

相关内容