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