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.
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()
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?
Thanks
To stop code execution in Python you first need to import the sys object. After this, you can then call the exit() method to stop the program from running.
# Simple script to start / stop a python script in the background. # To Use: # Just run: "./startstop.sh". If the process is running it will stop it or it will start it if not.
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
Contrast this with, say ctrl-C:
signal.getsignal(signal.SIGINT)
Out[65]: <function signal.default_int_handler> #i.e. something
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
to accept the two arguments that signal
will pass to it.sys.exit()
at the end of your byebye
function to allow python to gracefully close up shop. You could alternatively do some combination of signal
and atexit
:
import sys
signal.signal(signal.SIGTERM, lambda num, frame: sys.exit(0))
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With