I have a python script that launches a subprocess which then opens a python terminal window that displays its running logs/status output.
If the user closes the window, the process terminates - this is desirable. However, I cannot figure out a way to "catch" and log if the user manually terminates the script (closes window).
I have tried putting my main() in a try/except block but it seems that no exceptions are being raised (like a KeyboardInterrupt).
Also tried atexit package - but this seems only to take into effect at normal script termination.
Is there a way to log/print to file when a user terminates a script mid run?
Related
I am trying to launch mayapy with subprocess and route all output to a text file. This works, however I am noticing about 30% of the time the initial script that launches subprocess will hang in the window I run it in. The mayapy that was launched finishes fine, all output goes to the indicated stdout_file, but the main process that called it is hanging. A carriage return will usually cause the rest of it to finish and I'm unsure why. I've even added a sys.exit() call in the subprocess that is being run, yet it still hangs.
maya = subprocess.call(command, stdout=stdout_file, stderr=stdout_file, shell=True)
logger.info("Exitcode {}".format(maya))
if str(maya) != '0':
logger.error("Something went wrong...")
UPDATE: The main python script was started from within a Powershell window in Windows. The answer as to why this was happening relates entirely to that.
I feel a bit stupid that this was the entire reason the process was hanging.
https://serverfault.com/questions/204150/sometimes-powershell-stops-sending-output-until-i-press-enter-why
"If the QuickEdit Mode and\or Insert options are checked within the console\window properties, and you click within the console, it will pause the output. If those options are not checked, the output can't be paused by clicking within the console."
Since I turned off these options in the Powershell window, the process has yet to hang. Also explains why it was so sporadic and only happening on occasion if I accidentally clicked into the window.
So I am creating a script that needs to be run 24/7 on a server machine. I have created try/excepts to catch if the script stops for any reason and send me an email.
However, there is nothing that will happen if the command line is closed. Therefore, there will be no notification if the command line closes for any reason while the script stops.
I'm not sure how to add code to be able to do that, but it is important because I need to know anytime the script has been stopped. At the moment I can only check if it is stopped in any way except closing the window.
Here's a simple answer that I hope will work for you using python's atexit module:
import atexit
def exit_handler():
# do this stuff when the script exits
return
atexit.register(exit_handler)
Keep in mind the exit handler function won't execute if there is some sort of fatal internal error or it was terminated at a low level, but for this most part this should work :)
I am trying to implement some basic close out tasks for an automation script I have written in python using pyautogui. I open a program and click certain buttons every day to create daily reports. But if something goes wrong, I need it to close the program it is using.
I tried using atexit.register, but it didn't seem to run when I trigger sys.exit(). So I wrote a test script to verify that it was triggering, and it isn't.
import atexit as a
import sys
def closeout():
print("atexit triggered, closing out")
print("starting program")
print("Registering closeout with atexit")
a.register(closeout)
print(r"triggering sys.exit()")
sys.exit()
it should print out the following:
"starting program"
"Registering closeout with atexit"
"triggering sys.exit()"
"atexit triggered, closing out"
but I don't get the last line.
Any thoughts? I'm running 3.7.2 if it matters.
When you "run module" from IDLE, it uses the compile builtin to build a code object from the associated file, and then runs it with exec. The process that runs the code doesn't exit, and SystemExit is caught and silently ignored in the IDLE interpreter - otherwise a script that included it would cause IDLE to quit! - so the atexit handler isn't run.
Furthermore, the default build of IDLE is configured to delete any register atexit functions when exiting, so your handler isn't run when IDLE itself eventually exits. (See the exit function in the cpython repo.)
Basically I am writing a script that can be stopped and resumed at any time. So if the user uses, say PyCharm console to execute the program, he can just click on the stop button whenever he wants.
Now, I need to save some variables and let an ongoing function finish before terminating. What functions do I use for this?
I have already tried atexit.register() to no avail.
Also, how do I make sure that an ongoing function is completed before the program can exit?
Solved it using a really bad workaround. I used all functions that are related to exit in Python, including SIG* functions, but uniquely, I did not find a way to catch the exit signal when Python program is being stopped by pressing the "Stop" button in PyCharm application. Finally got a workaround by using tkinter to open an empty window, with my program running in a background thread, and used that to close/stop program execution. Works wonderfully, and catches the SIG* signal as well as executing atexit . Anyways massive thanks to #scrineym as the link really gave a lot of useful information that did help me in development of the final version.
It looks like you might want to catch a signal.
When a program is told to stop a signal is sent to the process from the OS, you can then catch them and do cleanup before exit. There are many diffferent signals , for xample when you press CTRL+C a SIGINT signal is sent by the OS to stop your process, but there are many others.
See here : How do I capture SIGINT in Python?
and here for the signal library: https://docs.python.org/2/library/signal.html
Quick Question: What signal/Exception does PyCharm's Stop Button send when debugging a python script?
Background: Several posts document that hitting Ctrl-C doesn't send a Keyboard Interrupt/SIGINT signal to a python script when using PyCharm's Debugger. Fine. My question is, what does get sent to the Python script when clicking the Debugger's "Stop Button". I'd like to re-write my code to catch whatever that signal/Exception is. [I'm using OSX w/PyCharm 4.0.4]
When you stop the process after debugging it, it sends a SIGKILL signal to the interpreter.
Process finished with exit code 137
Exit codes above 128 mean that it's a 128 + a signal's number (in this case, 9, which is a SIGKILL).
You could catch SIGTERM using signal.signal(), but SIGKILL can't be caught. There's nothing you can do with it.
Well, you could set up a separate script that would monitor the first one (checking for its PID existance in the running processes, for example) and do something if the given process is terminated.