[EDITED]
2 options for handling standard output from subprocess.Popen
are stdout="a_file_name"
and stdout=subprocess.PIPE
.
stderr
can be combined with either of those via stderr=subprocess.STDOUT
.
For what I'm currently doing (fuzz-testing), my resulting stdout="a_file_name"
code is slightly shorter and cleaner.
However, from what I’ve seen, it seems that stdout=PIPE
is often preferred by others, but I’m not sure of all of the reasons why.
If the cmd
used in Popen([cmd, arg], ...)
is an external executable which writes error output to stderr
, is stdout=PIPE
somehow better than stdout="a_file_name"
?
What are some pros and cons of each?
stdout=PIPE
rather than stdout="a_file_name"
is that the former would let me easily skip writing an empty file.cmd
crash, might 1 of the 2 somehow be more likely to get all of the error output?Although I have my particular context in mind, I'd be interested in knowing the answer(s) for the more general case as well.
To better explain my context, here are my 2 alternative code segments:
import subprocess
import sys
assert sys.version_info >= (3, 3)
# timeout added for subprocess's wait() and communicate() in Python 3.3.
with open('sub_proc1.outerr', 'w') as f_outerr1:
sub_proc1 = subprocess.Popen([cmd, args], stdout=f_outerr1,
stderr=subprocess.STDOUT,
universal_newlines=True)
try:
return_code = sub_proc1.wait(timeout=10)
print('*** %s CRASHED with return code: %d.' % (cmd, return_code))
except subprocess.TimeoutExpired:
print('*** %s succeeded.' % cmd)
sub_proc1.kill()
versus:
...
with open('sub_proc2.outerr', 'w') as f_outerr2:
sub_proc2 = subprocess.Popen([cmd, args], stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True)
try:
(sub_proc2_out, sub_proc2_err) = sub_proc2.communicate(timeout=10)
print('*** %s CRASHED with return code: %d.' %
(cmd, sub_proc2.poll()))
assert sub_proc2_err is None
# Since stderr was redirected to STDOUT, this should be None.
f_outerr2.write(str(sub_proc2_out or ""))
# Treat 'None' as an empty string).
except subprocess.TimeoutExpired:
print('*** %s succeeded.' % cmd)
sub_proc2.kill()
ORIGINAL POST:
TITLE: subprocess: Pros and cons of stderr=STDOUT vs. stderr=PIPE?
The 2 principal alternatives for handling error output from 'subprocess.Popen' seem to be 'stderr=STDOUT' (with 'stdout="some_file"') and 'stderr=PIPE'.
For what I want to do (fuzz-testing), my resulting 'stderr=STDOUT' code is a little shorter and cleaner.
However, from what I've read, it seems that 'stderr=PIPE' is preferred, but I'm not sure of all of the reasons why.
If the 'cmd' used is an external executable which writes error output to 'stderr', what are the pros and cons of using 'stderr=STDOUT' versus 'stderr=PIPE'?
...
Writing to a specific file means that your program will have conflicts if it is run more than once at a time since both processes will want to write to the same file. (search for issues with temporary file creation and security vulnerabilities)
Using a pipe means there is no issue of file name uniqueness.
Do you care about the output? If not, then use subprocess.DEVNULL
and it will discard the output for you.