Run code in python script on shutdown signal
python, raspberry-pi, shutdown
Solution
`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:
- 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.
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.
Problem
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