$ 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