I am writing a small Python script for Windows that runs a certain program using subprocess.Popen and then, after a while, kills it. I could use Popen.terminate or Popen.kill to terminate that program, however, as indicated by the docs, those would act the same by calling the Windows API function TerminateProcess. However, that function terminates the program immediately, which may result in errors. I would like to replicate the result of hitting the 'X' button, which uses the 'ExitProcess' function. Is that possible?
Related
I am running some Python code using a SLURM script on a remote server accessed through SSH. At some point, issues related to licenses on the SLURM platform may happen, generating errors in Python and ending the subprocess. I want to use try-except to let the Python subprocess wait until the issue is fixed, after that it can keep running from where it stopped.
What are some smart implementations for that?
My most obvious solution is just keeping Python inside a loop if the error occurs and letting it read a file every X seconds, when I finally fix the error and want it to keep running from where it stopped, I would write something on the file and break the loop. I wonder if there is a smarter way to provide input to the Python subprocess while it is running through the SLURM script.
One idea might be to add a signal handler for signal USR1 to your Python script like this.
In the signal handler function, you can set a global variable or send a message or set a threading.Event that the main process is waiting on.
Then you can signal the process with:
kill -USR1 <PID>
or with the Python os.kill() equivalent.
Though I do have to agree there is something to be said for the simplicity of your process doing:
touch /tmp/blocked.$$
and your program waiting in a loop with a 1s sleep for that file to be removed. This way you can tell which process id is blocked.
I made a script which plays a video file by using subprocess.run().
import subprocess
DATA_DIR = 'path\\to\\video\\files'
MEDIA_PLAYER = 'path\\to\\my\\media-player'
# returns path of random video file
p = chooseOne(DATA_DIR)
print('playing {}'.format(p))
# runs chosen path
subprocess.run([MEDIA_PLAYER, p])
But I would like to kill the python script running this code immediately after opening the child subprocess.
Is this possible? And if not, is there an alternative means of opening an external process using Python which would allow the script to terminate?
Note: I am using Python v3.6
Don't use subprocess.run; use os.execl instead. That makes your media player replace your Python code in the current process, rather that starting a new process.
os.execl(MEDIA_PLAYER, p)
subprocess.run effectively does the same thing, but forks first so that there are temporarily two processes running your Python script; in one, subprocess.run returns without doing anything else to allow your script to continue. In the other, it immediately uses one of the os.exec* functions—there are 8 different varieties—to execute your media player. In your case, you just want the first process to exit anyway, so save the effort of forking and just use os.execl right away.
I have a shell script which I am calling in Python using os.system("./name_of_script")
I would prefer to do this call based on user input(ie a user types "start" and the call is done, and some other stuff in the python program is also done, when a user types "stop" the script is terminated) but i find that this call takes up the whole focus on the terminal (I dont really know the right word for it, but basically the whole program stalls on this call since my shell script executes until a keyboard interrupt is received). Then when I do a keyboard interrupt, that is the only moment that the shell script stops executing and the rest of the code afterwards is executed. Is this possible in python?
Simply constructing a Popen object, as in:
p = subprocess.Popen(['./name_of_script'])
...starts the named program without blocking on it to complete.
If you later want to see if it's done yet, you can check p.poll() for an update on its status.
This is also faster and safer than os.system(), in that it doesn't involve a shell (unless the script you're invoking runs one itself), so you aren't exposing yourself to shellshock, shell injection vulnerabilities, or other shell-related issues unnecessarily.
I want to invoke an external GUI application from a python script which will be triggered upon some file upload to the server.
I would like the process to be launched and kept running whereas the python script should continue and eventually finish its job and quit. I have tried different options but none proved successful.
Right now the script expects the application to be closed before script exits and sends the response.
I tried Subprocess, Popen, os.System, Spawnl, Spawnlp in the main thread as well by calling these API's in a separate thread. There are lot of questions asked in this regard in stackoverflow and other forums. But I couldn't get the exact solution for this yet.
Appreciate any help.
had exactly the same problem and took me friggin ages to find it, but here is your answer:
import win32api
win32api.ShellExecute(0, "open", "python.exe", 'blah.py', '', 1)
This guarantees you an independent process - even after you exit the calling python program, this will continue to work.
Here's the scenario:
I have a Python script that is called from a browser with AJAX. I want the Python script to run and return its output, however if it fails to successfully run in 10 seconds, I want the script to abort and return some other process. Also, at the very beginning, I want to log what the request was.
Here's how I'm thinking of architecting it:
Commander script
Calls three scripts, spawned as subprocesses?
1. the main code to execute and return its result
2. a second script, that waits 10 seconds, then returns False
3. a third script, to log the request in a database
The commander script will return either the result from (1) or an error if it hears back from (2).
How would you actually implement this? I can't figure out if I should use the threading library or the os library with subprocesses.
Or is there a better way to do this?
If this script is run under Unix-like system, you may use SIGALRM to do it.
There's an example in python docs.
I highly sugges using the multiprocessing library of Python. It has process.terminate() methods.
check out:
subprocess.Popen.poll
and
subprocess.Popen.terminate