一、背景
从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.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() 终止子进程