python / 未分类 · 2013年11月11日

subprocess

1. subprocess以及常用的封装函数
Python有很几个模块都可以创建进程。最终我选择使用subprocess模块,因为在Python手册中有这样一段话:
  This module intends to replace several other, older modules and functions, such as: os.system、os.spawn*、os.popen*、popen2.*、commands.*
  subprocess被用来替换一些老的模块和函数,如:os.system、os.spawn*、os.popen*、popen2.*、commands.*。可见,subprocess是被推荐使用的模块。
返回退出信息(returncode,相当于exit code,见Linux进程基础)
#eg
[root@master 11]# python 1
文件系统 容量 已用 可用 已用% 挂载点
/dev/sda1 16G 3.6G 12G 25% /
tmpfs 298M 0 298M 0% /dev/shm
returncode: 0
[root@master 11]# cat 1
#!/usr/bin/python
import subprocess
returnCode = subprocess.call("df -h",shell=True)
print 'returncode:', returnCode
import subprocess
rc = subprocess.call(["ls","-l"])
import subprocess
out = subprocess.call("ls -l", shell=True)

我们使用了shell=True这个参数。这个时候,我们使用一整个字符串,而不是一个表来运行子进程。Python将先运行一个shell,再用这个shell来解释这整个字符串。
2. Popen
实际上,我们上面的三个函数都是基于Popen()的封装(wrapper)。这些封装的目的在于让我们容易使用子进程。当我们想要更个性化我们的需求的时候,就要转向Popen类,该类生成的对象用来代表子进程。
subprocess.PIPE
  在创建Popen对象时,subprocess.PIPE可以初始化stdin, stdout或stderr参数。表示与子进程通信的标准流。
subprocess.STDOUT
  创建Popen对象时,用于初始化stderr参数,表示将错误通过标准输出流输出
与上面的封装不同,Popen对象创建后,主程序不会自动等待子进程完成。我们必须调用对象的wait()方法,父进程才会等待 (也就是阻塞block):
#这个不错,mysql 导入就是用这个实现的呢
我们可以在Popen()建立子进程的时候改变标准输入、标准输出和标准错误,并可以利用subprocess.PIPE将多个子进程的输入和输出连接在一起,构成管道(pipe):
import subprocess
child1 = subprocess.Popen(["ls","-l"], stdout=subprocess.PIPE)
child2 = subprocess.Popen(["wc"], stdin=child1.stdout,stdout=subprocess.PIPE)
out = child2.communicate()
print(out)

[root@master 11]# python 2
(‘ 3 18 91\n’, None)
[root@master 11]# ls -l |wc
3 18 91
subprocess.PIPE实际上为文本流提供一个缓存区。child1的stdout将文本输出到缓存区,随后child2的stdin从该PIPE中将文本读取走。child2的输出文本也被存放在PIPE中,直到communicate()方法从PIPE中读取出PIPE中的文本。
要注意的是,communicate()是Popen对象的一个方法,该方法会阻塞父进程,直到子进程完成。
总结:
subprocess.call, subprocess.check_call(), subprocess.check_output()
subprocess.Popen(), subprocess.PIPE
Popen.wait(), Popen.communicate()
参考
http://www.cnblogs.com/vamei/archive/2012/09/23/2698014.html
http://blog.csdn.net/jgood/article/details/4498166
http://www.cnblogs.com/GODYCA/archive/2013/05/08/3066870.html