Last active
February 9, 2025 22:28
Script that captures both stdout and stderr in a way that works for subprocesses, while still being able to use rich own console to use original streams.
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
from rich.console import Console | |
from subprocess import run | |
import tempfile | |
import sys | |
from contextlib import redirect_stdout, redirect_stderr | |
# If we do not pass file=sys.stdout explicitly, rich output will also be | |
# captured by the context manager. | |
console = Console(file=sys.stdout) | |
console_err = Console(file=sys.stderr, stderr=True) | |
console.clear() | |
# We cannot use StringIO because the do not have a file descripor, which is | |
# needed for subprocesses. | |
captured_stdout = tempfile.TemporaryFile(mode="w+", prefix="stdout") | |
captured_stderr = tempfile.TemporaryFile(mode="w+", prefix="stderr") | |
with redirect_stdout(captured_stdout) as stdout: | |
with redirect_stderr(captured_stderr) as stderr: | |
console.print("[red]Hello[/], stdout world!") | |
console_err.print("[red]Hello[/], stderr world!") | |
run( | |
"echo 'subprocess-stdout' && echo 'subprocess-stderr' >&2", | |
shell=True, | |
check=False, | |
stdout=stdout, | |
stderr=stderr, | |
) | |
print("print-stdout") | |
print("print-stderr", file=sys.stderr) | |
captured_stdout.seek(0) | |
captured_stderr.seek(0) | |
print("captured-stdout: %s" % captured_stdout.readlines()) | |
print("captured-stderr: %s" % captured_stderr.readlines()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment