subprocess.run Link to heading
python 3.5 provided new interface to replace older os.system to call programs and shell commands. doc
run() is wrapper around the lower interface Popen which provides finer and more complicated control. Also, run waits until process is done but popen will continue execution and user needs to check for process termination.
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, capture_output=False, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None, universal_newlines=None, **other_popen_kwargs)
as docs mentions these are the most important options.
args Link to heading
This could be list of strings for the program and program arguments.
subproccess.run(["ls", "-l"])
if it’s one string, shell=True must be used to allow shell to handle the whole command
run ( "ls -l f*",shell=True)
stdin, stdout, stderr Link to heading
According to doc,
stdin, stdout and stderr specify the executed program’s standard input, standard output and standard error file handles, respectively. Valid values are PIPE, DEVNULL, an existing file descriptor (a positive integer), an existing file object, and None
import subprocess
print("########## default")
ls = subprocess.run(["ls"])
print((ls))
print("########## suppress output")
ls = subprocess.run(["ls"], stdout= subprocess.DEVNULL)
print("########## send to file")
fh = open("t","w")
ls = subprocess.run(["ls"], stdout= fh)
print("########## capture in process")
ls = subprocess.run(["ls"], stdout= subprocess.PIPE)
print(ls.stdout)
ls = subprocess.run(["ls"], stdout= subprocess.PIPE, text=True)
text Link to heading
by default, stdout, stdin, stderr are using byte encoding for output. with text=True, the output is string
In [10]: run ( "echo test",shell=True,stdout=subprocess.PIPE).stdout
Out[10]: b'test\n'
In [11]: run ( "echo test",shell=True,stdout=subprocess.PIPE, text=True).stdout
Out[11]: 'test\n'
subprocess.Popen Link to heading
Popen starts the process and user needs to check when it terminated if needed
proc = subprocess.Popen("sleep 10", shell=True)
try:
outs, errs = proc.communicate(timeout=3)
except subprocess.TimeoutExpired:
proc.kill()
outs, errs = proc.communicate()
print("timeout")
There is also Popen.wait which makes program wait for child process which make Popen() same as run()
also there are several API to control the process, probably the most important would be
- Popen.send_signal(signal)
- Popen.kill()