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 errorFileNotFoundError
-
Popen() 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