subprocess

一、背景

从Python 2.4开始,Python引入subprocess模块来管理子进程,以取代一些旧模块的方法:如 os.system、os.spawn*、os.popen*、popen2.*、commands.*不但可以调用外部的命令作为子进程,而且可以连接到子进程的input/output/error管道,获取相关的返回信息。python3也取消了之前在python中常用来获取运行linux命令行结果的commands.getstatusoutput()方法,因此,有必要逐渐熟悉新的方法。

 

二、常用封装函数

1、subprocess.call()

subprocess.call(["ls","-l"])

结果返回标准输出和returncode

subprocess_第1张图片

另一种调用方式:

subprocess.call("ls -l", shell=True)

shell默认为False,在Linux下,shell=False时, Popen调用os.execvp()执行args指定的程序;

shell=True时,如果args是字符串,Popen直接调用系统的Shell来执行args指定的程序,如果args是一个序列,则args的第一项是定义程序命令字符串,其它项是调用系统Shell时的附加参数。

2、subprocess.check_call()

subprocess.check_call(["cat","1.txt","2.txt"])

返回结果同call()方法一致,但若returncode不为0,则抛出异常CalledProcessError。可用try...except...来捕获

注:cat多个文件合成一个文件时,文件连接间用空行分隔了

3、subprocess.check_output()

 result=subprocess.check_output(["cat","1.txt","2.txt"])

返回标准输出的结果,且若returncode不为0,同样抛出CalledProcessError。例如:

subprocess.check_output("exit 1", shell=True)

 

以上三个函数都是父进程等待子进程完成,即等待命令完成才打印标准输出。 且都是Popen()的封装,subProcess.Popen()对象代表子进程。

三、底层函数

1、subprocess.Popen

1)指定stdout = subprocess.PIPE获取标准输出:

p1=subprocess.Popen("cat 1.txt 2.txt",shell=True,stdout=subprocess.PIPE)
p1.communicate()

运行结果为 标准输出,标准错误输出的元组:

('1\n2\n3\n\naa\nbb\ncc\n', None)

注意communicate的作用:

>与子进程进行交互。向stdin发送数据,或从stdout和stderr中读取数据。例如:

 p=subprocess.Popen("ls",shell=True,stdout=subprocess.PIPE)
 p.communicate("-l")

>Communicate()返回一个元组:(stdoutdata, stderrdata)

>subprocess.PIPE实际提供了一个缓冲区。communicate将数据从缓冲区读出来。

注:如果你设定了stdout = subprocess.PIPE,而子进程非常多时候,容易死锁。

2)管道间通信

p1 = subprocess.Popen(["cat","/etc/passwd"], stdout=subprocess.PIPE)
p2 = subprocess.Popen(["grep","0:0"],stdin=child1.stdout, stdout=subprocess.PIPE)
result = child2.communicate()

前一个进程的标准输出作为后一个进程的输入。

【注意】communicate()是Popen对象的一个方法,该方法会阻塞父进程,直到子进程完成。

 3)父进程可对子进程进行操作

p1.poll()  检查子进程是否已结束,设置并返回returncode属性

p1.wait() 等待子进程结束,设置并返回returncode属性

p1.kill()  终止子进程

p1.send_signal()  向子进程发送信号

p1.terminate() 终止子进程

 

你可能感兴趣的:(subprocess)