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 usesubprocess.run()
in many cases, but lots of existing code calls these functions.
subprocess.run common parameters
-
subprocess.run default behavior accepts arguments in list
subprocess.run(["ls", "-l"])
-
shell=True
(defaultFalse
) to send arguments in stringsubprocess.run("ls -l", shell=True)
-
capture_output=True
(defaultFalse
) to save output in a varres = subprocess.run("ls -l", shell=True, capture_output=True) res.stdout
-
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:
output=$(dmesg | grep hda)
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
Leave a comment