在关闭信号时在 python 脚本中运行代码 [英] Run code in python script on shutdown signal
问题描述
我有一个在启动时在后台运行的 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 thatsignal
will pass to it. - you should do something like call
sys.exit()
at the end of yourbyebye
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屋!