Linux:让systemd立即终止正在运行的Python脚本吗?

时间:2016-04-24 18:41:21

标签: python linux systemd sigint

我在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然后使用my.service监控systemctl的状态来尝试此操作时,my.service实际进入似乎需要一段时间' 失败 '状态(已停止)。似乎将ExecStop 调用到脚本并不足以以一分钟的方式终止my.service本身和后续的script.py

为了更清楚:我希望脚本能够以类似于 Ctrl + C 的方式立即终止 。基本的Python清理是可以的,但我不希望systemd等待“优雅”的响应超时,或类似的东西。

问题:

  1. 我对延迟的解释是正确的,还是只是systemctl更新其状态概述很慢?
  2. 停止服务和终止脚本的可行方法是什么?我应该在Python脚本中包含某种SIGINT捕获吗?如果是这样,怎么样?或者是否可以在my.service中完成某些操作以加快停止服务并杀死脚本?

2 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:1)

在单位部分选项下,您应该使用location / { try_files $uri $uri/ @rewrite; } location ~ \.php$ { try_files $uri @rewrite; fastcgi_pass ... ... } location @rewrite { rewrite ^/(.*)?$ /index.php?completeURL=$1 last; } 这类似于Requisite=other.service但是,如果此处列出的单位尚未启动,则不会启动它们,并且交易将立即失败。

为了在单位部分下再次触发脚本执行,您可以使用Requires=,这是一个空格分隔的一个或多个单位的列表,当该单位进入"失败"状态。

同样使用OnFailure=选项配置需求依赖项,风格与BindsTo=非常相似,但除此行为外,它还声明当列出的任何单位突然消失时,此单元将停止。如果服务终止于自己的选择,设备被拔出或卸载了挂载点而没有涉及systemd,则单位可能会突然意外消失。

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

From systemd.unit man