os.system stdout redirection...

mackstann mack at incise.org
Sun Aug 17 16:28:49 EDT 2003


On Sun, Aug 17, 2003 at 02:43:44PM -0500, Terry Gray wrote:
> mackstann wrote:
> >On Sun, Aug 17, 2003 at 01:01:41AM -0500, Terry Gray wrote:

> >You can use os.popen (popen2 and 3 as well), or the popen2 module's
> >Popen3 and 4 classes, or commands.getoutput (and there are probably even
> >more ways :).
> >
> All the Python docs I've been looking at must have been pre-2.0, because 
> this is the first I've heard of the popen2/3/Popen3/4 calls.  Anyway, is 
> there a recommended way of capturing 'make's' output, line by line, and 
> redirecting it to a PyQt window?  The window in question is a QTextEdit 
> control with a 'def write' function.
> 
> Again, thanks for the help.

Probably the simplest way is something like:

import os
prog = os.popen("echo hello")
print prog.read()

--> 'hello\n'

It's basically a file-like interface for running shell commands.  You
can also open with "w" or "rw" and write to the command's stdin, or you
can use popen2/3/4 to have individual descriptors for stdin / stdout /
stderr.  The popen2 module seems to be less cross-platform, at least
with regard to the Popen3/4 classes, as I see this in popen2.py:

if sys.platform[:3] == "win":
    # Some things don't make sense on non-Unix platforms.
    del Popen3, Popen4

But if you plan on only using unix, then Popen3/4 are kinda nice, if you
like a more OOPey interface, or want more process management abilities.
Example:

import popen2
prog = popen2.Popen3("echo hello; read i; echo $i")
print prog.fromchild.read()

--> 'hello\n'

There's also .tochild, to write to its stdin, and Popen4 has childerr,
for reading stderr.  You can also do prog.poll() and prog.wait(), if you
need to check if it's still running, or wait for it to exit, and you can
get its pid via prog.pid.

So it kinda depends on whether you need to read from the command as
you're doing something else, or you want to just wait for it all to come
out at once.

import popen2

prog = popen2.Popen3("make spaghetti 2>&1")
output = ""

while 1:
  text = prog.read()
  if text:
    output += text

At least, I'm pretty sure that's how you detect that the program is done
(reading '').  I've only used Popen3 to interface with mpg321, and it
sends a little quit message when it's done, and then I close it, so I
haven't had to check for when it exits.

If you need to read bits from it while you're simultaneously doing other
things, you can use prog.fromchild.fileno() with select.select(), for
example.  Or launch a thread, or other things I'm sure.

-- 
m a c k s t a n n  mack @ incise.org  http://incise.org
My weight is perfect for my height -- which varies





More information about the Python-list mailing list