概述
subprocess 模块可以启动一个新进程,并连接到它们的输入/输出/错误管道,获取进程执行的结果。Popen 是 subprocess的核心, 负责子进程的创建和管理, run() 方法可以便捷的获取进程的返回结果。
subprocess.Popen()
"""
# 常用参数(入参)
# args
shell 命令:可以是字符串或者序列类型(list or tuple)
# bufsize
缓冲区大小:创建标准流的管道对象时使用, 默认值:-1
0 : 不使用缓冲区
1 : 表示行缓冲,仅当 universal_newlines=True时可用(也就是文本模式时)
正数 : 表示缓冲区的大小
负数 : 表示使用默认的缓冲区大小
# stdin, stdout, stderr
分别表示程序的标准输入、输出、错误句柄
# preexec_fn
只有在Unix平台下有效,用于指定一个可执行对象,它将在子进程运行之前被调用
# shell
如果该参数为True, 将通过操作系统的shell执行指定命令
# cwd
用于设置子进程的当前目录
# env
用于指定子进程的环境变量
如果 env=None, 则子进程的环境变量将从父进程中继承
# encoding
设置编码类型
cn:
mac : utf-8
windows : gb2312
# Popen 对象的方法/属性
## poll():
检查进程是否终止,如果终止返回returncode,否则返回None
## wait(timeout):
等待子进程终止,可以指定超时时间
## communicate(input, timeout):
与子进程交互,发动和读取数据
## send_signal():
发送信号到子进程
## terminate():
停止子进程,即是发送SIGTERM信号到子进程
## kill():
杀掉子进程,即是发送SIGKILL信号到子进程
# Popen 返回对象
返回对象一般都是二进制的标准输入、输出和错误句柄
"""
# 应用举例
import subprocess
import logging
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%a, %d %b %Y %H:%M:%S',
filename='main.log',
filemode='w')
console = logging.StreamHandler()
console.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
console.setFormatter(formatter)
logging.getLogger('').addHandler(console)
try:
p = subprocess.Popen('pip list',
bufsize=1,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
shell=True,
universal_newlines=True,
cwd=None,
encoding='utf-8'
)
except Exception as e:
logging.exception(e)
else:
logging.info(p.args)
logging.info(p.communicate()[0])
logging.info(p.poll())
subprocess.run()
# 常用参数(入参)
# args
shell 命令:可以是字符串或者序列类型(list or tuple)
# stdin, stdout, stderr
分别表示程序的标准输入、输出、错误句柄, 默认值均是None
若要与程序交互,则需要设置stdin
若需获取输出和错误,则需要设置stdout, stderr
一般设置为subprocess.PIPE
文件对象设置为subprocess.DEVNULL
stderr也可以设置为subprocess.STDOUT
表示将错误重定向到stderr指定的管道
# shell
默认值为False
若为True:
args参数可以是复杂字符串,同人为在linux中输入命令一样
若为False:
args命令中包含参数,则必须以命令列表的方式传入
一般可以通过shlex.split(string)处理即可
# universal_lines
若为True:
stdin,stdout,stderr均已字符串方式读写,
若为False:
stdin,stdout,stderr以字节流方式读写
# cwd
用于设置子进程的当前目录(执行路径)
运行非shell命令时,可以用来指定程序的所在路径
# timeout
命令超时时间,当程序超过指定时间没有返回时,则会抛出异常
###引用举例import subprocess
import logging
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%a, %d %b %Y %H:%M:%S',
filename='main.log',
filemode='w')
console = logging.StreamHandler()
console.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
console.setFormatter(formatter)
logging.getLogger('').addHandler(console)
try:
p = subprocess.run('pip list',
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
shell=True,
universal_newlines=True,
cwd=None,
timeout=5,
)
except Exception as e:
logging.exception(e)
else:
logging.info(p.args)
logging.info(p.returncode)
logging.info(p.stdout)

被折叠的 条评论
为什么被折叠?



