Linux:让 systemd 立即终止 运行 Python 脚本?

Linux: Make systemd kill a running Python script immediately?

我在 Raspbian 上使用 systemd 到 运行 一个 Python 脚本 script.pymy.service 文件如下所示:

[Unit]
Description=My Python Script
Requires=other.service

[Service]
Restart=always
ExecStart=/home/script.py
ExecStop=/home/script.py

[Install]
WantedBy=multi-user.target

Required=other.service 停止时,我希望 my.service 立即停止并终止 Python 进程 运行ning script.py.

但是,当通过停止 other.service 然后使用 systemctl 监视 my.service 的状态来尝试时,my.service 似乎需要一段时间才能完成实际上进入了一个'failed'状态(停止)。似乎调用 ExecStop 到脚本 不足以终止 my.service 本身和随后的 script.py

要特别清楚:我希望脚本以类似于 Ctrl + [= 的方式 立即 终止45=]C。基本 Python 清理没问题,但我不希望 systemd 等待 'graceful' 响应超时或类似的情况。

问题:

  1. 我对延迟的解释是否正确,或者只是 systemctl 更新其状态概述很慢?
  2. 停止服务和终止脚本的推荐方法是什么。我是否应该在 Python 脚本中包含某种 SIGINT 捕获?如果是这样,如何?或者是否可以在 my.service 中做一些事情来加快服务的停止和脚本的终止?

我认为你应该研究一下 TimeoutStopSec and it's default value param DefaultTimeoutStartSec。在提供的链接上,有一些关于 WatchdogSec 的更多信息以及您可能会发现有用的其他选项。看起来 DefaultTimeoutStartSec 的默认值是 90 秒,这可能是您遇到的延迟..?

在单元部分选项下,您应该使用 Requisite=other.service 这类似于 Requires= 但是,如果此处列出的单元尚未启动,则它们将不会启动并且交易将立即失败。

要在单元部分再次触发脚本执行,您可以使用 OnFailure=,这是一个 space 分隔的一个或多个单元列表,当该单元进入 "failed"状态。

同样使用BindsTo=选项配置需求依赖,在风格上与Requires=非常相似,但是除了这种行为,它还声明当任何一个单元突然列出时该单元停止消失。如果服务自行终止、设备被拔出或挂载点在没有 systemd 参与的情况下卸载,单元可能会突然、意外地消失。

我认为在你的情况下 BindsTo= 是可以使用的选项,因为它会导致当前单元在关联单元终止时停止。

From systemd.unit man