1.介绍
通过subprocess模块可以在python程序中开设一个子进程, 该子进程在shell中执行相关命令然后主进程可获取其运行结果
2.Popen对象
通过Popen可开启子进程, Popen为非阻塞的:
class subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=(), *, encoding=None, errors=None, text=None)
使用示例:
import subprocess
# 正常情况下不推荐设置shell为True, 出于安全考虑( The only time you need to specify shell=True on Windows is when the command you wish to execute is built into the shell (e.g. dir or copy). )
# 如果设置encoding,或text=True,或error参数, 结果返回为字符串而不是字节
# Popen对象不会阻塞
obj= subprocess.Popen(['ipconfig'], shell=False, stdout=subprocess.PIPE, encoding='gbk')
# obj.wait() # 等待子进程结束, 如果设置stdout等参数可能因为pipe变满而死锁
# print(obj.stdout.read()) # obj.stdout为文件句柄, 可以读出子进程运行的结果,前提必须设置stdout参数
print(obj.communicate()[0]) # 更推荐使用communicate(), 该函数等待子进程结束,并且不会造成死锁
obj.kill() # 及时杀死子进程释放内存
3.subprocess.run()
run()函数为Popen的高级封装, 可满足一般的使用, 但它是阻塞的, 须等待子进程执行后才执行后面的内容;
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None)
大部分参数与Popen相同, 但除了以下参数:
1)capture_output:设置是否捕获运行结果
If capture_output is true, stdout and stderr will be captured. When used, the internal Popen object is automatically created with stdout=PIPE and stderr=PIPE. The stdout and stderr arguments may not be used as well.
2)timeout: 会自动传入communicate()中
The timeout argument is passed to Popen.communicate(). If the timeout expires, the child process will be killed and waited for. The TimeoutExpired exception will be re-raised after the child process has terminated.
3)input: 会自动传入communicate()中
The input argument is passed to Popen.communicate() and thus to the subprocess’s stdin. If used it must be a byte sequence, or a string if encoding or errors is specified or text is true. When used, the internal Popen object is automatically created with stdin=PIPE, and the stdin argument may not be used as well.
4)check: 如果进程运行出错会抛出异常
If check is true, and the process exits with a non-zero exit code, a CalledProcessError exception will be raised. Attributes of that exception hold the arguments, the exit code, and stdout and stderr if they were captured.
run()返回一个CompletedProcess对象具有以下属性:
args
The arguments used to launch the process. This may be a list or a string.
returncode
Exit status of the child process. Typically, an exit status of 0 indicates that it ran successfully.
A negative value -N indicates that the child was terminated by signal N (POSIX only).
stdout
Captured stdout from the child process. A bytes sequence, or a string if run() was called with an encoding, errors, or text=True. None if stdout was not captured.
If you ran the process with stderr=subprocess.STDOUT, stdout and stderr will be combined in this attribute, and stderr will be None.
stderr
Captured stderr from the child process. A bytes sequence, or a string if run() was called with an encoding, errors, or text=True. None if stderr was not captured.
check_returncode()
If returncode is non-zero, raise a CalledProcessError.
使用:
obj2 = subprocess.run(['ipconfig'], capture_output=True, encoding='gbk')
print(obj2.stdout)