Skip to content

Instantly share code, notes, and snippets.

@ssbarnea
Last active March 30, 2023 11:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ssbarnea/3ba3a278300aef1acba394bb03234a31 to your computer and use it in GitHub Desktop.
Save ssbarnea/3ba3a278300aef1acba394bb03234a31 to your computer and use it in GitHub Desktop.
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