T90
T90

Reputation: 577

Python check if force closed

Suppose I have a python file 'program.py' running in a terminal window. I need that program to log something like say 'force closed' to a file when the window in which it was running was terminated manually. I've read that the program sends a status code of -1 for unsuccessful execution, but how do I read and do something based on that?

Upvotes: 6

Views: 3777

Answers (2)

Ludovic Viaud
Ludovic Viaud

Reputation: 202

you can't do that, if the process is killed the program is over, he can't do additional things before disappear. For the return code it's different, every program has a return code, by convention 0 means no problem, all other value indicates a problem, but it's only when a program terminate, not get killed. You also have a process status, and signal, it can give you the informations you want, but not in the script himself. So for what you want you will need 2 script, one script which launch and observe a second script (with Popen) and check if a specific signal was sent to the 2nd script

edit : this is for linux only and will not works if the parent get killed too, for windows you will need the pywin32 module, it's possible to catch a console closed, I don't know for the right-click => close on task manager but try https://danielkaes.wordpress.com/2009/06/04/how-to-catch-kill-events-with-python/

Upvotes: 1

freakish
freakish

Reputation: 56547

You can't. A process can't read it's own exit code. That would not make much sense. But in order to force process shutdown the OS has to send a signal to that process. As long as it is not SIGKILL and/or SIGSTOP then you can intercept it via signal library. SIGKILL and SIGSTOP cannot be blocked, e.g. if someone does kill -9 then there's nothing you can do.

To use signal library:

import signal
import sys

def handler(signum, frame):
    # do the cleaning if necessary

    # log your data here
    with open('log.log', 'a') as fo:
        fo.write('Force quit on %s.\n' % signum)

    # force quit
    sys.exit(1)  # only 0 means "ok"

signal.signal(signal.SIGINT, handler)
signal.signal(signal.SIGHUP, handler)
signal.signal(signal.SIGTERM, handler)

When terminal closes it sends SIGHUP to a process.

SIGINT is used for CTRL-C interruption.

SIGTERM is similar to SIGKILL. The difference is that the process can catch it. It's a "graceful kill".

IMPORTANT: This is true for all POSIX systems. I don't know much about other OS.

Upvotes: 8

Related Questions