Search code examples
python-3.xsubprocesspipestdoutpopen

What is the difference between suprocess.run(['ls', '-la'], capture_output=True).stdout and suprocess.check_output(['ls', '-la'])?


I am a beginner in Python and I can not seem to find a difference between the following two,

import subprocess

test1 = subprocess.run(['ls', '-la'], capture_output=True)
print(test1.stdout)

test2 = subprocess.check_output(['ls', '-la'])
print(test2)

I find both test1 and test2 to be giving me the same thing. What is the difference?

Also two terms that I do not understand when googled about this is 'Popen constructor' and 'pipe'. Would be helpful if you can elaborate on both of these too and how they relate to the subprocess module.


Solution

  • Passing the capture_output parameter to subprocess.run is new in Python 3.7.

    subprocess.check_output is the older high-level API (docs):

    Prior to Python 3.5, these three functions comprised the high level API to subprocess. You can now use run() in many cases, but lots of existing code calls these functions.

    Older APIs remain for backwards compatibility - there's little benefit to removing them, and a long deprecation period would be needed to avoid breaking existing code.

    Popen ("process open") is the lower level API which will be internally used by run, check_output, etc. The "Popen constructor" is documented here.

    A subprocess pipe is just the subprocess API's abstraction of inter-process communication features provided by the underlying operating system. For example, using a shell ls -la | grep needle would connect the stdout of ls to the stdin of grep with a pipe |. To do similar in subprocess API, you may pass the special value subprocess.PIPE as the stdout handle when spawning a subprocess. You may think of a pipe as a small FIFO buffer which channels the output of one process to the input of another.