I'm trying to capture the error message of a program called by subprocess.check_call
but the stderr
in the error object is always None
.
Here is a short script that shows this:
import subprocess
import sys
if '--fail' in sys.argv: # the script calls itself with this option, for the test
print('this is the error message', file=sys.stderr)
sys.exit(1)
try:
subprocess.check_call([sys.executable, sys.argv[0], '--fail'],
stdout=subprocess.DEVNULL, stderr=subprocess.PIPE)
print('Not failed?') # this neither happens nor is expected
except subprocess.CalledProcessError as err:
if err.stderr:
print(err.stderr.decode()) # this is what I expect
else:
print('<No error message>') # this is what happens
I have Python 3.10.12.
You didn't communicate with the subprocess at all, so the content is still buffered in the pipe.
The docs of check_call
have this notice:
Note: Do not use
stdout=PIPE
orstderr=PIPE
with this function.
Instead of this:
subprocess.check_call([sys.executable, sys.argv[0], '--fail'],
stdout=subprocess.DEVNULL, stderr=subprocess.PIPE)
Use the higher level API of run:
subprocess.run([sys.executable, sys.argv[0], '--fail'],
capture_output=True, check=True)