Python difference on subprocess run(), call(), check_call(), check_output()#
Difference on subprocess run(), call(), check_call(), check_output()#
Since Python 3.5, the official doc explains that:
Prior to Python 3.5, these three functions (subprocess.call(), subprocess.check_call(), subprocess.check_output()) comprised the high level API to subprocess. You can now use subprocess.run() in many cases, but lots of existing code calls these functions.
subprocess.run common parameters#
- subprocess.run default behavior accepts arguments in list
 
shell=True(defaultFalse) to send arguments in string
capture_output=True(defaultFalse) to save output in a var
encoding="utf-8"(defaultNone) to save var in string instead of bytes.check=True(defaultFalse) to raisesubprocess.CalledProcessError: if command returned non-zero exit code. But if the command executable doesn't exist for exampel missspellm you will get the errorFileNotFoundErrorPopen() is for advanced usage. For example, replacing the shell pipeline.
shell command:
with Popen, becomes:
p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
output = p2.communicate()[0]
- default params
 
import subprocess
default_run_params = dict(
    capture_output=True,
    encoding="utf-8",
    check=True
)
# command = ["unknown_command", "-l"]
# command = ["python", "-askjd"]
command = ["ls", "-l"]
try:
    # output type is subprocess.CompletedProcess
    output = subprocess.run(command, **default_run_params)
    # print in pure string in one line
    print(output)
    # print with new line just as launching from shell
    print(output.stdout)
    # as we catch error with `check=True`,
    # output.stderr is always an empty string.
    # and output.returncode is always 0 in this case.
except FileNotFoundError as exc:
    print(f"{type(exc).__name__}: {exc}")
    raise
except subprocess.CalledProcessError as exc:
    print(exc)  # no error details will given by print(exc)
    print(exc.__dict__)  # print all
    print(exc.returncode)
    print(exc.stderr)  # print error message only
    # exc.stdout should be empty
    raise