Getting stdout and stderr from popen
Stefan Heimann
stefan.heimann at web.de
Wed Mar 6 18:26:03 EST 2002
Donn Cave <donn at u.washington.edu> wrote::
> Quoth Jonathan Gardner <jgardn at alumni.washington.edu>:
>| Stefan Heimann scribbled with his keyboard:
>|> I want to launch an external process and have stdout and stderr
>|> redirected to one output stream,
>|
>| You are on Unix, right?
>|
>|> something like
>|>
>|> f = os.popen('cvs status 2>&1')
>|>
>|> does the right thing, but does not work on all platforms.
>
> Apparently he is not on UNIX? That's the right answer, as long
> as popen() runs the UNIX shell.
I am on unix but I want it to work on windows, too.
>
>|> If I write
>|>
>|> pin, pout, perr = os.popen3('cvs status')
>|>
>|> I get the output of stderr and stdout but not in the right order.
>|
>| What do you mean in the right order? Do you mean that it is returning in,
>| err, out or that err and out are spitting out stuff simultaneously?
the latter one.
>
> Probably not simultaneous, because the C I/O library probably has
> thread interlocks that prevent it, but if you want a single time
> ordered stream, you'd need time stamps to reassemble it out of
> two. For example, suppose you record the output of "make", which
> will be both output and error streams. If you read them separately,
> you won't be able to tell which compiler errors belong to which
> make commands.
That's what I need! Is it really so complicated? I think it should be
common that someone needs to read stdout and stderr ordered by time.
>
>| Okay, let's talk about what is really happening deep underneath the hood.
>|
>| These popen functions are a shorthand for a very common thing in the world
>| of Unix. It goes something like this:
>|
>| 1) make three pipes (in, out, err)
>| 2) fork.
>
> I beg your pardon, but that's really not common at all. Most UNIX
> pipes are created using the shell, which makes a pipe for output only.
> If you want a separate pipe for error, you're in for some gymnastics -
> (cvs status 2>&3 | sed s/^/out:/) 3>&1 1>&2 | sed s/^/err:/
> And there's no Bourne shell formula at all to get all three on pipes.
> More recent shells have features that could be exploited for that,
> but it gets hairy.
>
> This is not just nitpicking, because there are real good reasons why
> it isn't all that common. It's surprisingly difficult to get two
> processes to cooperate reliably over multiple pipes. That's my second
> point here - even if separate output and error streams are OK in terms
> of the data, they're distinctly more difficult to deal with if you
> don't make some simplifying assumptions about how the other process
> is going to behave.
>
> The shell syntax to route both streams into the pipe is really the
> right way to go, if it works. If it doesn't work, we'd have to know
> why not, before suggesting any answer. (If it doesn't work on Windows,
> then someone else is going to have to answer it - and the subject line
> probably should have included "Windows" in the first place.)
Hm, I haven't tested it on Windows, but I *know* that the shell syntax
won't work. I didn't think that it is so complicated ;-)
Bye Stefan
More information about the Python-list
mailing list