Computer Science Atlas
Snippets

Python 3: Get Standard Output and Standard Error from subprocess.run()

Part 3 of a Series: subprocess.run()
July 14, 2021
 
Articles in Series: subprocess.run()
  1. Python 3: Execute a System Command Using subprocess.run()
  2. Python 3: Get and Check Exit Status Code (Return Code) from subprocess.run()
  3. Current Article
    Python 3: Get Standard Output and Standard Error from subprocess.run()
  4. Python 3: Standard Input with subprocess.run()
  5. Python 3: Using Shell Syntax with subprocess.run()
  6. Python 3: Specify Environment Variables in subprocess.run()
Table of Contents

Using capture_output (Python 3.7 and Up)

On Python 3.7 or higher, if we pass in capture_output=True to subprocess.run(), the CompletedProcess object returned by run() will contain the stdout (standard output) and stderr (standard error) output of the subprocess:

from subprocess import run

p = run( [ 'echo', 'hello' ], capture_output=True )

print( 'exit status:', p.returncode )
print( 'stdout:', p.stdout.decode() )
print( 'stderr:', p.stderr.decode() )
1
2
3
4
5
6
7
from subprocess import run

p = run( [ 'echo', 'hello' ], capture_output=True )

print( 'exit status:', p.returncode )
print( 'stdout:', p.stdout.decode() )
print( 'stderr:', p.stderr.decode() )

p.stdout and p.stderr are bytes (binary data), so if we want to use them as UTF-8 strings, we have to first .decode() them.

Using PIPE

Alternatively, on any Python 3 version that supports subprocess.run() (i.e., 3.5 and up), we can pass in subprocess.PIPE into the stdout and stderr options to capture output:

from subprocess import run, PIPE

p = run( [ 'echo', 'hello' ], stdout=PIPE, stderr=PIPE )

print( 'exit status:', p.returncode )
print( 'stdout:', p.stdout.decode() )
print( 'stderr:', p.stderr.decode() )
1
2
3
4
5
6
7
from subprocess import run, PIPE

p = run( [ 'echo', 'hello' ], stdout=PIPE, stderr=PIPE )

print( 'exit status:', p.returncode )
print( 'stdout:', p.stdout.decode() )
print( 'stderr:', p.stderr.decode() )

Use Popen for Real Time Output

Because subprocess.run() waits for the command to finish running before returning, we'll receive the entire contents of stdout and stderr as a whole only after the command has completed. If we need to stream output as it appears in real time, we can use Popen instead.