Is it possible to detect and interrupt linux (Ubuntu 16.04) shutdown signal (e.g. power button clicked or runs out of battery). I have a python application that is always recording a video and I want to detect such signal so I close the recording properly before OS shutdown.
Schedule a time that suits your needs by using the format hh:mm (24-hour time designations). It's more likely that you'll want to halt the operating system a few minutes into the future. In that case, specify the number of minutes from now to begin the shutdown process.
Runlevel 0 is used to halt the system, runlevel 6 is used to reboot the system, and runlevel 1 is used to put the system into a state where administrative tasks can be performed (single-user mode).
Cancel a shutdown You can use the -c option to cancel a scheduled shutdown.
When linux is shut down, all processes receive SIGTERM
and if they won't terminate after some timeout they are killed with SIGKILL
. You can implement a signal handler to properly shutdown your application using the signal
module. systemd
(opposed to upstart
in earlier Ubuntu verions) additionally sends SIGHUP
on shutdown.
To verfiy that this actually works, I tried the following script on two Ubuntu VMs (12.04 and 16.04). The system waits for 10s (12.04/upstart) or 90s (16.04/systemd) before issuing SIGKILL
.
The script ignores SIGHUP
(which would otherwise also kill the process ungracefully) and will continuously print the time since the SIGTERM
signal has been received to a text file.
Note I used disown
(built-in bash command) to detach the process from the terminal.
python signaltest.py &
disown
signaltest.py
import signal
import time
stopped = False
out = open('log.txt', 'w')
def stop(sig, frame):
global stopped
stopped = True
out.write('caught SIGTERM\n')
out.flush()
def ignore(sig, frsma):
out.write('ignoring signal %d\n' % sig)
out.flush()
signal.signal(signal.SIGTERM, stop)
signal.signal(signal.SIGHUP, ignore)
while not stopped:
out.write('running\n')
out.flush()
time.sleep(1)
stop_time = time.time()
while True:
out.write('%.4fs after stop\n' % (time.time() - stop_time))
out.flush()
time.sleep(0.1)
The last line printed into log.txt
was:
10.1990s after stop
for 12.04 and
90.2448s after stop
for 16.04.
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