关机信号在python脚本中运行代码

时间:2014-02-06 20:47:06

标签: python raspberry-pi shutdown

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

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

#!/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"方法?有什么想法吗?

由于

1 个答案:

答案 0 :(得分:4)

shutdown发送SIGTERM信号,atexit无法处理。上下文管理员也不会finally阻止等等。

import signal

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

对比这个,比如ctrl-C:

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

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

signal.signal(signal.SIGTERM,byebye)

如果您执行上述操作,则需要执行以下两项操作:

  • 更改byebye的签名以接受signal将传递给它的两个参数。
  • 你应该在sys.exit()函数的末尾调用byebye之类的东西,让python优雅地关闭商店。

您也可以选择signal atexit的某种组合:

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

哪个会直接进入您当前的代码。这样可以确保清理操作的原子性(即byebye保证是最后的I / O操作),但代价是有点笨拙。