From the examples in docs on subprocess.run() it seems like there shouldn't be any output from
subprocess.run(["ls", "-l"]) # doesn't capture outputHowever, when I try it in a python shell the listing gets printed. I wonder if this is the default behaviour and how to suppress the output of run().
2 Answers
Here is how to suppress output, in order of decreasing levels of cleanliness. They assume you are on Python 3.
- You can redirect to the special
subprocess.DEVNULLtarget.
import subprocess
subprocess.run(['ls', '-l'], stdout=subprocess.DEVNULL)
# The above only redirects stdout...
# this will also redirect stderr to /dev/null as well
subprocess.run(['ls', '-l'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
# Alternatively, you can merge stderr and stdout streams and redirect
# the one stream to /dev/null
subprocess.run(['ls', '-l'], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)- If you want a fully manual method, can redirect to
/dev/nullby opening the file handle yourself. Everything else would be identical to method #1.
import os
import subprocess
with open(os.devnull, 'w') as devnull: subprocess.run(['ls', '-l'], stdout=devnull)Here is how to capture output (to use later or parse), in order of decreasing levels of cleanliness. They assume you are on Python 3.
NOTE: The below examples use
text=True.
- This causes the STDOUT and STDERR to be captured as
strinstead ofbytes.
- Omit
text=Trueto getbytesdatatext=Trueis Python >= 3.7 only, useuniversal_newlines=Trueon Python <= 3.6
universal_newlines=Trueis identical totext=Truebut more verbose to type but should exist on all Python versions
- If you simply want to capture both STDOUT and STDERR independently, AND you are on Python >= 3.7, use
capture_output=True.
import subprocess
result = subprocess.run(['ls', '-l'], capture_output=True, text=True)
print(result.stdout)
print(result.stderr)- You can use
subprocess.PIPEto capture STDOUT and STDERR independently. This works on any version of Python that supportssubprocess.run.
import subprocess
result = subprocess.run(['ls', '-l'], stdout=subprocess.PIPE, text=True)
print(result.stdout)
# To also capture stderr...
result = subprocess.run(['ls', '-l'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
print(result.stdout)
print(result.stderr)
# To mix stdout and stderr into a single string
result = subprocess.run(['ls', '-l'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
print(result.stdout) 10 ex: to capture the output of ls -a
import subprocess
ls = subprocess.run(['ls', '-a'], capture_output=True, text=True).stdout.strip("\n")
print(ls) 2