Reputation: 13246
I am trying to run the Robocopy
command (but I am curious about any subprocess) from Python in windows. The code is pretty simple and works well. It is:
def copy():
with Popen(['Robocopy', media_path, destination_path, '/E', '/mir', '/TEE', '/log+:' + log_path], stdout=PIPE, bufsize=1, universal_newlines=True) as Robocopy:
Robocopy.wait()
returncode = Robocopy.returncode
Additionally I am running it in a separate thread with the following:
threading.Thread(target=copy, args=(media_path, destination_path, log_path,), daemon=True)
However, there are certain instances where I want to stop the robocopy
(akin to closing the CMD
window if it was run from the command line)
Is there a good way to do this in Python?
Upvotes: 0
Views: 1242
Reputation: 414835
If the process doesn't start other processes then process.kill()
should work:
import subprocess
class InterruptableProcess:
def __init__(self, *args):
self._process = subprocess.Popen(args)
def interrupt(self):
self._process.kill()
I don't see why would you need it on Windows but you could run Thread(target=self._process.wait, daemon=True).start()
if you'd like.
If there is a possibility that the process may start other processes in turn then you might need a Job object to kill all the descendant processes. It seems killableprocess.py
which is suggested by @rrauenza uses this approach (I haven't tested it). See Python: how to kill child process(es) when parent dies?.
Upvotes: 1
Reputation: 6993
We fought with reliably killing subprocesses on Windows for a while and eventually came across this:
https://github.com/andreisavu/python-process/blob/master/killableprocess.py
It implements a kill()
method for killing your subprocess. We've had really good results with it.
You will need to somehow pass the process object out of the thread and call kill()
from another thread, or poll in your thread with wait()
using a timeout while monitoring some kind of global-ish flag.
Upvotes: 1