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 output
However, 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()
.
Here is how to suppress output, in order of decreasing levels of cleanliness. They assume you are on Python 3.
subprocess.DEVNULL
target.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)
/dev/null
by 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.
capture_output=True
.import subprocess
result = subprocess.run(['ls', '-l'], capture_output=True)
print(result.stdout)
print(result.stderr)
subprocess.PIPE
to capture STDOUT and STDERR independently. This does work on Python versions < 3.7, such as Python 3.6.import subprocess
result = subprocess.run(['ls', '-l'], stdout=subprocess.PIPE)
print(result.stdout)
# To also capture stderr...
result = subprocess.run(['ls', '-l'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
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)
print(result.stdout)
NOTE: By default, captured output is returned as bytes
. If you want to capture as text (e.g. str
), use universal_newlines=True
(or on Python >=3.7, use the infinitely more clear and easy-to-understand option text=True
- it's the same a universal_newlines
but with a different name).