Python 内建包-subprocess

1. wiki

subprocess 是 Python 2.4 中新增的一个模块,它允许你生成新的进程,连接到它们的 input/output/error 管道,并获取它们的返回(状态)码。

1.1. Popen

subprocess 模块中定义了一个 Popen 类,通过它可以来创建进程,并与其进行复杂的交互。

1
2
3
4
5
__init__(self, args, bufsize=0, executable=None, 
stdin=None, stdout=None, stderr=None, preexec_fn=None,
close_fds=False, shell=False, cwd=None, env=None,
universal_newlines=False, startupinfo=None,
creationflags=0)

主要参数说明:

  • args : 必须是一个字符串或者序列类型(如:字符串、list、元组),用于指定进程的可执行文件及其参数。如果是一个序列类型参数,则序列的第一个元素通常都必须是一个可执行文件的路径。当然也可以使用 executeable 参数来指定可执行文件的路径。
  • stdin,stdout,stderr : 分别表示程序的标准输入、标准输出、标准错误。有效的值可以是 PIPE,存在的文件描述符,存在的文件对象或 None,如果为 None 需从父进程继承过来,stdout 可以是 PIPE,表示对子进程创建一个管道,stderr 可以是 STDOUT,表示标准错误数据应该从应用程序中捕获并作为标准输出流 stdout 的文件句柄。
  • shell : 如果这个参数被设置为 True,程序将通过 shell 来执行。
  • env : 它描述的是子进程的环境变量。如果为 None,子进程的环境变量将从父进程继承而来。

2. 使用

2.1. 创建 Popen 类实例对象

创建 Popen 类的实例对象

1
res = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

参数含义:

  • cmd : 标准像子进程传入需要执行的 shell 命令,如:ls -al
  • subprocess.PIPE : 在创建 Popen 对象时,其可以初始化为 stdin, stdoutstderr的参数,表示与子进程通信的标准输入流,标准输出流以及标准错误
  • subprocess.STDOUT:作为Popen对象的stderr的参数,表示将标准错误通过标准输出流输出

2.2. Popen 类拥有的方法及属性

  • Popen.pid : 获取子进程的进程ID
  • Popen.returncode : 获取进程的返回码。如果进程未结束,将返回 None
  • communicate(input=None) : 与子进程进行交互,向 stdin 发送数据,并从 stdoutstderr 读出数据存在一个 tuple 中并返回。参数 input 应该是一个发送给子进程的字符串,如果未指定数据,将传入 None。
  • send_signal(sig) : 发送信号给子进程
  • poll() : 检查子进程是否结束,并返回 returncode 属性
  • wait() : 等待子进程执行结束,并返回 returncode 属性,如果为 0 表示执行成功
  • terminate() : 终止子进程。windows 下将调用 Windows API TerminateProcess()来结束子进程
  • kill() : 跟 terminate() 是一样的,表示杀死子进程

3. 举例

命令交互,不断从键盘接受命令执行,给出执行结果,直到用户输入 exit 或者 bye 退出命令交互

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import subprocess

class Shell(object) :
def runCmd(self, cmd) :
res = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
sout ,serr = res.communicate()
return res.returncode, sout, serr, res.pid

shell = Shell()
while 1 :
input = raw_input('>')
if input == 'exit' or input == 'bye' :
break
else :
result = shell.runCmd(input)
print "返回码:", result[0]
print "标准输出:", result[1]
print "标准错误:", result[2]