Getting stdout and stderr from subprocess in correct order

Piet van Oostrum piet-l at
Sat Mar 4 10:37:27 EST 2017

"Ivan \"Rambius\" Ivanov" <rambiusparkisanius at> writes:

> Dear colleagues,
> I using subprocess module and I am wondering how I can get the output
> of the spawned process's stdout and stderr in the right order. Here
> are my sample programs:
> $ cat
> import subprocess
> import sys
> f = ''
> p =[sys.executable, f], stdout=subprocess.PIPE,
> stderr=subprocess.PIPE)
> print(p.stdout)
> print(p.stderr)
> $ cat
> import sys
> print("a", file=sys.stdout)
> print("b", file=sys.stderr)
> print("c", file=sys.stdout)
> print("d", file=sys.stderr)
> When i run I get
> $ ./
> a
> b
> c
> d
> When I run it through, I do get standard out and standard
> errors streams, but they are separated and not in the order above:
> $ ./
> b'a\nc\n'
> b'b\nd\n'
> How should I use subprocess in order to get the outputs in the correct
> order? Thank you for your help in advance.
If you want them in the order they are produced then you have to put
them through a single channel with stderr=subprocess.STDOUT.

p =[sys.executable, f], stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, encoding='ascii')

I added an encoding so that it will be read as a text file rather than
binary. And of course you should read only stdout (stderr will give

Moreover you must make sure that each write is flushed. This can be done
in three ways:

1. Add the flush=True argument to the print statements.
print("a", file=sys.stdout, flush=True)
print("b", file=sys.stderr, flush=True)
print("c", file=sys.stdout, flush=True)
print("d", file=sys.stderr, flush=True)

2. Change the files to a line buffered version.
import os
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 1)
sys.stderr = os.fdopen(sys.stderr.fileno(), 'w', 1)

3. Add a flush() call after each print statement, like

Then you get them in order.
$ python3

Of course you won't be able to tell from which stream each line comes.
The streams are byte streams, not message streams. You would have to put
extra information, e.g. a prefix, in your print statements.
Piet van Oostrum <piet-l at>
PGP key: [8DAE142BE17999C4]

More information about the Python-list mailing list