subprocess.Popen():
在一些复杂场景中,我们需要将一个进程的执行输出作为另一个进程的输入。在另一些场景中,我们需要先进入到某个输入环境,然后再执行一系列的指令等。这个时候我们就需要使用到suprocess的Popen()方法。该方法有以下参数:
args:shell命令,可以是字符串,或者序列类型,如list,tuple。
bufsize:缓冲区大小,可不用关心
stdin,stdout,stderr:分别表示程序的标准输入,标准输出及标准错误
shell:与上面方法中用法相同
cwd:用于设置子进程的当前目录
env:用于指定子进程的环境变量。如果env=None,则默认从父进程继承环境变量
universal_newlines:不同系统的的换行符不同,当该参数设定为true时,则表示使用\n作为换行符
'''
主要用的的参数就是:args、stdin、stdout、stderr、shell(官方推荐shell=False)
1、args参数:可以是字符串也可以是列表(官方推荐)
如果是list,第一个元素是程序的路径,后面的元素为命令。但是如果程序配在环境变量里可以直接用环境变量的值表示。
例如:adb配置到环境变量,
process = subprocess.Popen(['adb', 'devices'], shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE))
print(process.communicate())
等同于:
process = subprocess.Popen(['D:\environment\android-sdk_r24.4.1-windows\android-sdk-windows\platform-tools\adb.exe', 'devices'],
shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE))
print(process.communicate())
***注意是adb的命令不是doc的命令***
如果想用doc命令可以这样用
process = subprocess.Popen(['cmd', 'dir'], shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE))
print(process.communicate()) 会打印所在目录的文件及文件夹
2、stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE:
分别代表标准输入,标准输出,标准错误输出。subprocess.PIPE代表的是管道可以理解成线程
3、shell参数表示是否是在shell环境下一般设置为False,想要在shell环境下执行命令process = subprocess.Popen(['adb', 'shell', ''shell命令]即可
4、communicate()方法打印的是标准输出和标准错误输出
5、想要输出stdout管道的内容可以用
outMsg = process.stdout.readlines() 输出的是list,process.stdout是字节流对象用readlines()读取文件内容;
errMsg = process.stderr.readlines() 同理
stdin是写入可以用write()方法,参数必须是bytes类型
import subprocess
obj = subprocess.Popen(['adb', 'shell', 'getprop ro.product.model'], shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
obj.stdin.write(b'qwe')
outIn = obj.communicate()
print(outIn)
6、
示例将一个子进程的输出,作为另一个子进程的输入:
import subprocess
child1 = subprocess.Popen(['adb', 'shell', 'getprop ro.product.model'], stdout=subprocess.PIPE)
child2 = subprocess.Popen(["grep","0:0"],stdin=child1.stdout, stdout=subprocess.PIPE)
out = child2.communicate()
7、
poll()、kill()、terminate()、方法待补充
''' 待更新
8、subprocess.getoutput()方法可以打印控制台的信息,返回的是字符串信息。收集log的时候可以用
例:1:devices = subprocess.getoutput('adb devices')
print(devices)
2:主程序执行完毕之后adb logcat自动结束进程
log_txt = open('log.txt', 'w')
cleanLog = 'adb logcat -c'
logcmd = 'adb logcat -v time'
subprocess.Popen(cleanLog, stdout=subprocess.PIPE, stdin=subprocess.PIPE, shell=True)
time.sleep(1) # 代码运行很快防止清理log时就开始了抓取log
subprocess.Popen(logcmd, stdout=log_txt, stdin=subprocess.PIPE, shell=True)
time.sleep(2) # 为了可以不丢失log
os.system('adb kill-server')