[Python 2.4/2.5] subprocess module is sorely deficient?
Nick Craig-Wood
nick at craig-wood.com
Tue Apr 22 08:30:02 EDT 2008
Harishankar <v.harishankar at gmail.com> wrote:
> Sorry to start off on a negative note in the list, but I feel that the Python
> subprocess module is sorely deficient because it lacks a mechanism to:
>
> 1. Create non-blocking pipes which can be read in a separate thread (I am
> currently writing a mencoder GUI in Tkinter and need a full fledged process
> handler to control the command line and to display the progress in a
> text-box)
>
> 2. Kill the subprocess in a platform independent manner (i.e. no third party
> modules and no hacks).
You are correct on both of those points. Subprocess isn't for
interacting with subprocesses - this should be written in large
letters in the help!
> Is there any way to use non-blocking Popen objects using
> subprocess?
There is a recipe in the cookbook
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/440554
Which I've used and it works.
you can also (if on unix) use
http://www.noah.org/wiki/Pexpect
I think the best solution would be to port Pexpect to windows which
wouldn't be that difficult according to my reading of the code. If
only I had more free time!
> and 2 - is there a way to kill the subprocess in a platform
> independent manner in a purely Pythonic way? I thought initially
> that this problem is simple enough, but over the last couple of
> days I've been really struggling to find any answer. I've been
> through dozens of mailing list archives in to find a
> solution. Unfortunately none of the solutions seem to fit my needs.
No...
This is the best I came up with to add to the subprocess recipe above
import os
from subprocess import *
from subprocess import mswindows
from time import sleep
if mswindows:
import win32api
else:
import signal
class PopenNB(Popen):
# - see cookbook recipe for rest of stuff
# ...
def kill(self, killpg=False):
"""
Kill the running process
"""
pid = self.pid
if mswindows:
# Kill the process using win32api and pid - ignore errors
try:
PROCESS_TERMINATE = 1
handle = win32api.OpenProcess(PROCESS_TERMINATE, False, pid)
win32api.TerminateProcess(handle, -1)
win32api.CloseHandle(handle)
except pywintypes.error:
pass
else:
# Kill the process by sending the pid / process group a
signal
if killpg:
try:
pgid = os.getpgid(pid)
except OSError:
killpg = False
try:
if killpg:
os.killpg(pgid, signal.SIGTERM)
else:
os.kill(pid, signal.SIGTERM)
except OSError:
return
sleep(1.0)
try:
if killpg:
os.killpg(pgid, signal.SIGKILL)
else:
os.kill(pid, signal.SIGKILL)
except OSError:
return
--
Nick Craig-Wood <nick at craig-wood.com> -- http://www.craig-wood.com/nick
More information about the Python-list
mailing list