I'd like to both capture and display the output of a process that I invoke through Python's subprocess.
I thought I could just pass my file-like object as named parameter stdout and stderr
I can see that it accesses the fileno
attribute - so it is doing something with the object.
However, the write()
method is never invoked. Is my approach completely off or am I just missing something?
class Process(object):
class StreamWrapper(object):
def __init__(self, stream):
self._stream = stream
self._buffer = []
def _print(self, msg):
print repr(self), msg
def __getattr__(self, name):
if not name in ['fileno']:
self._print("# Redirecting: %s" % name)
return getattr(self._stream, name)
def write(self, data):
print "###########"
self._buffer.append(data)
self._stream.write(data)
self._stream.flush()
def getBuffer(self):
return self._buffer[:]
def __init__(self, *args, **kwargs):
print ">> Running `%s`" % " ".join(args[0])
self._stdout = self.StreamWrapper(sys.stdout)
self._stderr = self.StreamWrapper(sys.stderr)
kwargs.setdefault('stdout', self._stdout)
kwargs.setdefault('stderr', self._stderr)
self._process = subprocess.Popen(*args, **kwargs)
self._process.communicate()
Update:
Something I'd like to work as well, is the ANSI control characters to move the cursor and override previously output stuff. I don't know whether that is the correct term, but here's an example of what I meant: I'm trying to automate some GIT stuff and there they have the progress that updates itself without writing to a new line each time.
Update 2
It is important to me, that the output of the subprocess is displayed immediately. I've tried using subprocess.PIPE to capture the output, and display it manually, but I was only able to get it to display the output, once the process had completed. However, I'd like to see the output in real-time.