【问题标题】:Linux: Make systemd kill a running Python script immediately?Linux:让 systemd 立即杀死正在运行的 Python 脚本?
【发布时间】:2016-04-24 18:41:21
【问题描述】:

我在 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 立即停止并终止运行script.py 的Python 进程。

但是,当通过停止 other.service 然后使用 systemctl 监视 my.service 的状态来尝试此操作时,my.service 似乎需要很长时间才能实际输入“失败'状态(停止)。似乎调用ExecStop 到脚本 不足以终止my.service 本身和随后的script.py

更清楚一点:我希望脚本以类似于 Ctrl + C 的方式结束立即。基本的 Python 清理工作还可以,但我不希望 systemd 等待“正常”响应超时或类似情况。

问题:

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

【问题讨论】:

  • 你试过用BindsTo代替Requires吗?
  • @DougLuce 总的来说,这看起来是个不错的建议。但是我现在试了一下,systemctl的状态还是my.service loaded deactivating stop至少一分钟才变成loaded failed failed
  • 这里不是主题。
  • @black 我不这么认为,尤其是如果在 Python 中捕获 SIGINT 是必需的方法。
  • 问题主要不是这个,这就是为什么它离题了。处理 SIGINT 会是,但它是次要的,除了几乎肯定已经讨论过。

标签: python linux systemd sigint


【解决方案1】:

我认为您应该查看TimeoutStopSec,它的默认值参数DefaultTimeoutStartSec。在提供的链接上,有一些关于WatchdogSec 的更多信息以及您可能会发现有用的其他选项。看起来DefaultTimeoutStartSec 的默认值是 90 秒,这可能是您遇到的延迟..?

【讨论】:

    【解决方案2】:

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

    要在单元部分再次触发脚本执行,您可以使用OnFailure=,这是一个以空格分隔的一个或多个单元的列表,当该单元进入“失败”状态时,这些单元会被激活。

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

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

    From systemd.unit man

    【讨论】:

    • 添加到我的答案中,我认为您应该使用BindsTo=,这就足够了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-14
    • 2015-08-18
    • 2020-10-11
    相关资源
    最近更新 更多