subprocess 模块主要用于创建子进程,并连接它们的输入、输出和错误管道,获取它们的返回状态。通俗地说就是通过这个模块,你可以在 Python 的代码里执行操作系统级别的命令,比如ipconfig
、du -sh
等。
大多数情况下,推荐使用run()方法调用子进程,执行操作系统命令,在更高级的使用场景,还可以调用Popen接口,其中run()方法在底层调用的就是Popen接口.
subprocess.run
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, timeout=None, check=False, encoding=None, errors=None)
功能,执行args参数所表示的命令,等待命令结束,返回一个CompletedProcess类型对象
注意:执行 args 参数所表示的命令,等待命令结束,并返回一个 CompletedProcess 类型对象.
args:
表示要执行的命令,必须是一个字符串,字符串参数列表
stdin,stdout和stderr:
子进程的标准输入,输出和错误.值可以是subprocess.PIPE
、subprocess.DEVNULL
、一个已经存在的文件描述符、已经打开的文件对象或者 None。
subprocess.PIPE
表示为子进程创建新的管道,subprocess.DEVNULL
表示使用os.devnull
。默认使用的是 None,表示什么都不做。另外,stderr 可以合并到 stdout 里一起输出
timeout
设置命令超时时间。如果命令执行时间超时,子进程将被杀死,并弹出TimeoutExpired
异常。
check
如果该参数设置为 True,并且进程退出状态码不是 0,则弹出CalledProcessError
异常。
encoding
如果指定了该参数,则stdin、stdout 和 stderr 可以接收字符串数据,并以该编码方式编码。否则只接收 bytes 类型的数据。
shell
如果该参数为True,将通过操作系统的shell执行指定的命令
subprocess.CompletedProcess
run()方法的返回值,表示一个进程结束了,CompleteProcess类有下面这些属性:
-
args 启动进程的参数,通常是个列表或字符串
-
returncode 进程结束状态返回码,0表示成功状态
-
设置了参数
stderr=subprocess.STDOUT
,则错误信息会和 stdout 一起输出,此时 stderr 的值是 None。stdout获取子进程的stdout,通常为bytes类型序列,None表示没有捕获值,如果在调用run()方法的时候, -
stderr 获取子进程的错误信息。通常为 bytes 类型序列,None 表示没有捕获值。
-
check_returncode() 用于检查返回码。如果返回状态码不为零,弹出
CalledProcessError
异常。
subprocess.DEVNULL
一个特殊值,用于传递给 stdout、stdin 和 stderr 参数。表示使用os.devnull
作为参数值
subprocess.PIPE
管道,可传递给 stdout、stdin 和 stderr 参数
subprocess.STDOUT
特殊值,可传递给 stderr 参数,表示 stdout 和 stderr 合并输出。
args与shell
args 参数可以接收一个类似'du -sh'
的字符串,也可以传递一个类似['du', '-sh']
的字符串分割列表。shell 参数默认为 False,设置为 True 的时候表示使用操作系统的 shell 执行命令。
获取执行结果
run()方法返回的是一个CompletedProcess类型对象,不能直接获取我们想要的结果,要想获取想要执行的结果或者信息,在调用run方法的时候,指定stdout=subprocess.PIPE
subprocess.Popen()
用法和参数run()方法基本相同,但是他的返回值是一个Popen对象,而不是CompletedProcess对象
Popen对象的stdin,stdout,stderr是三个文件的句柄,可以像文件那样进行读写操作
要实现python命令功能,可以按一下操作
import subprocess
s = subprocess.Popen("python", stdout=subprocess.PIPE, stdin=subprocess.PIPE, shell=True)
s.stdin.write(b"import os
")
s.stdin.write(b"print(os.environ)")
s.stdin.close()
out = s.stdout.read().decode("GBK")
s.stdout.close()
print(out)