Script to capture stderr of subprocess

Nobody nobody at nowhere.com
Wed Oct 20 21:36:24 CEST 2010


On Tue, 19 Oct 2010 11:21:49 -0700, jslowery at gmail.com wrote:

> Actually, if it was possible, it would be nice to capture all
> the bytes going between stdin and stdout in a file as well for
> debugging purposes.

If the child process expects to be running on a terminal, you would need
to use a pseudo-terminal (pty). See the "pty" module (although the
documentation assumes that you already understand how Unix ptys work).

Redirecting stdin/stdout to pipes tends to interfere with interactive
behaviour for a whole variety of reasons. Not least of which being that
many programs specifically use something like isatty(fileno(stdin)) to
determine whether they are being run interactively.

> cmd = ['/usr/local/bin/runcobol'] + sys.argv[1:]
> proc = subprocess.Popen(cmd, stderr=subprocess.PIPE)
> proc.communicate()
> 
> if proc.returncode:
>     f = file('/tmp/boom.txt', 'w')
>     f.write(" ".join(cmd) + " returned unexpectedly.\n")
>     f.write(proc.stderr.read(-1))
>     f.close()
> sys.exit(proc.returncode)

The .communicate() method waits for the process to terminate. Once that
has happened, you can't call .read() on proc.stderr.

The .communicate method returns a tuple, where the first item is whatever
was written to stdout (provided that stdout was redirected to a pipe), and
the second item is whatever was written to stderr (provided that stderr
was redirected to a pipe).

So you should use e.g.:

	errors = proc.communicate()[1]




More information about the Python-list mailing list