subprocess.wait()与subprocess.communicate()使用问题
subprocess就是开启一个子进程,自己去执行命令,这个子进程的状态肯定得收集,这时候就需要调用wait或者communicate了,手册上面也注明了这两个方法的特点:在数据超过PIPE的缓存时,wait会阻塞进程;communicate会把所有的数据都读取到内存中
那么现在就有一个问题了,当我shell命令执行的结果很大时,我是该用wait还是communicate?用wait直接就阻塞了,肯定不行,用communicate也不行,如果很大的文件,数据都保存在内存,主机直接就卡死了。
解决办法:数据一行一行读取,读取完之后wait,这样既保证了不会阻塞(PIPE中数据有进有出,最后空了才wait),又保证了不会占用大量主机内存(在内存中的数据只有一行line)。
p1=subprocess.Popen(comm1,shell=True,stdout=subprocess.PIPE)
for line in p1.stdout:
pass
p1.wait()
subprocess.Popen():
在一些复杂场景中,我们需要将一个进程的执行输出作为另一个进程的输入。在另一些场景中,我们需要先进入到某个输入环境,然后再执行一系列的指令等。这个时候我们就需要使用到suprocess的Popen()方法。该方法有以下参数:
args:shell命令,可以是字符串,或者序列类型,如list,tuple。
bufsize:缓冲区大小,可不用关心
stdin,stdout,stderr:分别表示程序的标准输入,标准输出及标准错误
shell:与上面方法中用法相同
cwd:用于设置子进程的当前目录
env:用于指定子进程的环境变量。如果env=None,则默认从父进程继承环境变量
universal_newlines:不同系统的的换行符不同,当该参数设定为true时,则表示使用\n作为换行符
例如:
a = subprocess.Popen('mkdir subprocesstest',shell=True,cwd='/root')
还有:
import subprocess
child1 = subprocess.Popen(["cat","/etc/passwd"], stdout=subprocess.PIPE)
child2 = subprocess.Popen(["grep","0:0"],stdin=child1.stdout, stdout=subprocess.PIPE)
out = child2.communicate()