Last active
March 13, 2024 23:57
-
-
Save igorsantos07/160dc637eece5957125bb61e4746b424 to your computer and use it in GitHub Desktop.
stderr doesn't get captured when stdout=sys.stdout
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
############################################################################# | |
# Reproducible example for https://stackoverflow.com/q/78152055/102960 | |
# The objective is to see the presentation line, the prompt line, be able to | |
# answer it, and then have stderr captured and omitted from normal console | |
# output. | |
# Run THIS script from CLI, not script.py | |
############################################################################# | |
import shlex | |
import subprocess | |
import sys | |
print('Initial setup - the output here is unrelated to the actual problem: downloading MariaDB image') | |
mariadb = subprocess.run(('docker', 'ps', '-f', 'name=example-mariadb'), capture_output=True, text=True) | |
if 'example-mariadb' in mariadb.stdout: | |
print('MariaDB container is already running') | |
else: | |
subprocess.run(shlex.split('docker run --detach --name example-mariadb --env MARIADB_DATABASE=db --env MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=1 mariadb:10.6.16')) | |
# Original test script got abandoned, since Python's input() seems q bit buggy, but it's not the actual issue; | |
# Other than that, captured output behaves as expected, differently from the MariaDB issue | |
# cmd = './script.py' | |
cmd = shlex.split('docker exec -it example-mariadb mariadb-admin drop wrong-db') | |
# For some reason, the prompt doesn't show up in stdout, but in stderr? | |
print('The same script.py will be called THREE times') | |
print('First: stdout=sys.stdout, so you should see a presentation line, then the question - answer "y"') | |
result = subprocess.run(cmd, text=True, stderr=subprocess.PIPE, stdout=sys.stdout) | |
print(result) | |
# > CompletedProcess(args='./script.py', returncode=1, stderr='Should I work without throwing errors? [y/N] Cool! Take this error: ERROR ERROR ERROR\n') | |
print() | |
print('Second: stderr=PIPE stdout=None, so you should see a presentation line, then the question - answer "y"') | |
# the same happens if stdout is omitted, | |
# or if I try to check captured stderr from CalledProcessError instead | |
try: | |
subprocess.run(cmd, text=True, check=True, stderr=subprocess.PIPE) | |
except subprocess.CalledProcessError as error: | |
print(vars(error)) | |
# > {'returncode': 1, 'cmd': './script.py', 'output': None, 'stderr': 'Should I work without throwing errors? [y/N] Cool! Take this error: ERROR ERROR ERROR\n'} | |
print() | |
print('Third: stderr=stdout=PIPE, so you should NOT see the presentation nor the question, but answer "y" anyway') | |
# However, if I also capture stdout, it works as expected... | |
# But then, the user cannot really interact, since the question | |
# is captured and never shown. The same happens if I try..except. | |
result = subprocess.run(cmd, text=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE) | |
print(result) | |
# > CompletedProcess(args='./script.py', returncode=1, stdout='This is the test script, writing to stdout. Now, the question:\nShould I work without throwing errors? [y/N] ', stderr='Cool! Take this error: ERROR ERROR ERROR\n') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import sys | |
print('This is the test script, writing to stdout. Now, the question:') | |
response = input('Should I work without throwing errors? [y/N] ') | |
if response.lower() == 'y': | |
print('Ok, no error then, but no problems either.') | |
else: | |
print('Cool! Take this error: ERROR ERROR ERROR', file=sys.stderr) | |
sys.exit(1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment