3

I am running a python script in the background using the command python script.py &. The script might look like this.

import time

def loop():
    while True:
        time.sleep(1)

if __name__=='__main__':
    try:
        loop()
    except KeyboardInterrupt:
        print("Terminated properly")

When it comes to terminating the script, I would like to do some cleanup before it is stopped (such as printing "Terminated properly"). If I run as a current process, this would be handled by the except statement after a keyboard interrupt.

Using the kill PID command means the cleanup is never executed. How can I stop a background process and execute some lines of code before it is terminated?

henneray
  • 449
  • 3
  • 10
  • 1
    you can use `kill -s 2 PID` to send a keyboard interrupt to process `PID`. Um... it should be signal `2` if there is no mistake with my memory. – Sraw Oct 07 '17 at 12:56
  • 1
    `kill` sends a different signal than `KeyboardInterrupt`. By default, it sends `INT (2)` you can read more about it here http://linuxcommand.org/lc3_man_pages/kill1.html – Chen A. Oct 07 '17 at 12:56
  • 1
    @Vinny signal 9 is SIGKILL... – Maya Oct 07 '17 at 12:57
  • 1
    Thanks! The `kill -s 2 PID` worked perfectly. – henneray Oct 07 '17 at 13:05

2 Answers2

2

You can use signal module to catch any signals sent to your script via kill. You setup a signal handler to catch the signal in question that would perform the cleanup.

import signal
import time

running = 0

def loop ():
    global running
    running = 1
    while running:
        try: time.sleep(0.25)
        except KeyboardInterrupt: break
    print "Ended nicely!"

def cleanup (signumber, stackframe):
    global running
    running = 0

signal.signal(signal.SIGABRT, cleanup)
signal.signal(signal.SIGTERM, cleanup)
signal.signal(signal.SIGQUIT, cleanup)
loop()
Dalen
  • 4,128
  • 1
  • 17
  • 35
0

Use finally clause:

def loop():
    while True:
        time.sleep(1)

if __name__=='__main__':
    try:
        loop()
    except KeyboardInterrupt:
        print("Terminated properly")
    finally:
        print('executes always')
temasso
  • 1,104
  • 8
  • 6
  • The `finally` clause does not seem to be executed when using the `kill PID` command. – henneray Oct 07 '17 at 13:06
  • Please check this Q/A [How to run one last function before getting killed in Python?](https://stackoverflow.com/questions/930519/how-to-run-one-last-function-before-getting-killed-in-python). – temasso Oct 07 '17 at 13:15