在关闭信号时在 python 脚本中运行代码 [英] Run code in python script on shutdown signal

查看:34
本文介绍了在关闭信号时在 python 脚本中运行代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个在启动时在后台运行的 python 脚本.启动方法是使用/etc/rc.local 调用的 run.sh 文件中的一个条目.确切的条目是sudo python/home/pi/run/main.py &".系统是带有喘息的树莓派.

I have a python script that runs in the background on startup. The starting method is a entry in a run.sh file which is called with /etc/rc.local. The exact entry would be "sudo python /home/pi/run/main.py &". The system is a raspberry pi with wheezy.

脚本正在运行,目前没有问题.如果关闭命令发送到系统(通过控制台sudo shutdown -h now"),我需要进一步的脚本不要立即中止,而是先执行一些代码.这就是我到目前为止所得到的:

The script is running, no problem so far. If a shutdown command is send to the system (via console "sudo shutdown -h now") I need further the script to not abort right away but to execute some code first. Thats what I got so far:

#!/usr/bin/env python

import atexit

@atexit.register
def byebye():
    c = "End"
    datei = open("/home/pi/logfile",'a+b')
    datei.write(c + "\n")
    datei.close()

def main():

   while True:
     ...do anything...

main()

现在似乎只是在关闭时退出主循环.我是否需要使用不同的方式来关闭系统以便将信号传输到我的脚本,或者我可能没有使用@atexit"方法?有什么想法吗?

Right now it seems to just exit the main loop on shutdown. Do I need to use a different way to shutdown the system so the signal is transmitted to my script or did I maybe not get the usage of the "@atexit" method? Any ideas?

谢谢

推荐答案

shutdown 发送 SIGTERM 信号,atexit 不处理.上下文管理器、finally 等也不会阻塞.

shutdown sends the SIGTERM signal, which atexit does not handle. Nor will context managers, finally blocks, etc.

import signal

signal.getsignal(signal.SIGTERM)
Out[64]: 0 #i.e. nothing

对比一下,说 ctrl-C:

Contrast this with, say ctrl-C:

signal.getsignal(signal.SIGINT)
Out[65]: <function signal.default_int_handler> #i.e. something

你可以用 signal 注册你的 byebye 函数来运行而不是什么都不做(这会导致解释器最终被 shell 杀死)

You can register your byebye function with signal to run instead of doing nothing (which leads to the interpreter eventually getting killed by the shell)

signal.signal(signal.SIGTERM,byebye)

如果您执行上述操作,则需要做两件事:

If you do the above you'll need to do two things:

  • 更改byebye 的签名以接受signal 将传递给它的两个参数.
  • 您应该在 byebye 函数的末尾调用 sys.exit() 之类的操作,以允许 python 优雅地关闭商店.
  • change the signature of byebye to accept the two arguments that signal will pass to it.
  • you should do something like call sys.exit() at the end of your byebye function to allow python to gracefully close up shop.

你也可以组合signal atexit:

import sys
signal.signal(signal.SIGTERM, lambda num, frame: sys.exit(0))

这将直接放入您当前的代码中.这确保了清理操作的原子性(即 byebye 保证是最后一个 I/O 操作),但代价是有点笨重.

Which would drop right in to your current code. This ensures the atomicity of your cleanup operation (i.e. byebye is guaranteed to be the last I/O operation) at the cost of being a bit clunky.

这篇关于在关闭信号时在 python 脚本中运行代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆