Skip to content

Instantly share code, notes, and snippets.

@ssbarnea
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.
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