Pranjal Doshi
Pranjal Doshi

Reputation: 1262

Capturing subprocess in console and python

I'm trying to execute some bash command using python. I want to display command's live output to user as well as capture it.
A sample example is like

import subporcess

# This will store output in result but print nothing to terminal
result = subprocess.run(['ls', '-lh'], check=True, universal_newlines=True, stdout=subprocess.PIPE)
print(result.stdout) # STD OUTPUT
# This will print everything to terminal result will be empty
result = subprocess.run(['ls', '-lh'], check=True, universal_newlines=True)
print(result.stdout) # OUTPUT = None

Upvotes: 0

Views: 873

Answers (1)

Simon Bowly
Simon Bowly

Reputation: 1073

Here is one possibility which will gather output lines from a long-running process, write them to terminal as it goes, and return them all when the process exits.

It returns a list of output lines, rather than a full block of text that check_output or run would return, but that's easily changed. Perhaps an IO buffer might be more efficient depending on how much output you're expecting.

import subprocess
import sys

def capture_and_echo_stdout(cmd):
    """ Start a subprocess and write its stdout to stdout of this process.     
    Capture and return stdout lines as a list. """
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
    stdout_lines = []
    for line in proc.stdout:
        sys.stdout.write(line.decode())
        stdout_lines.append(line)
    proc.communicate()
    # Roughly equivalent to check=True
    if proc.returncode:
        raise subprocess.CalledProcessError(proc.returncode, cmd)
    return stdout_lines

There are a few similar options in this answer (although the focus there is more on writing to multiple files like unix tee): How to replicate tee behavior in Python when using subprocess?

Upvotes: 2

Related Questions