subprocess模块提供进程间操作

call方法创建一个子进程

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

结果:

-rw------- 1 root root     1570 Feb  3  2015 anaconda-ks.cfg
drwxr-xr-x 2 root root     4096 Feb  3  2015 Desktop
-rw-r--r-- 1 root root    59038 Feb  3  2015 install.log
-rw-r--r-- 1 root root     5266 Feb  3  2015 install.log.syslog
-rw-r--r-- 1 root root   908984 May 18 12:29 nginx-1.9.15.tar.gz
-rw-r--r-- 1 root root  2053336 May 18 18:12 pcre-8.38.tar.gz
-rw-r--r-- 1 root root 18207283 May 18 18:13 php-7.0.6.tar.gz
-rw-r--r-- 1 root root   148960 May 18 09:42 zabbix-2.2.1-1.el5.x86_64.rpm
-rw-r--r-- 1 root root   248051 May 18 09:41 zabbix-agent-2.2.1-1.el5.x86_64.rpm
-rw-r--r-- 1 root root    11296 May 18 09:33 zabbix-release-2.4-1.el6.noarch.rpm

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

>>> retcode=subprocess.call("ls -l",shell=True)
total 21244
-rw------- 1 root root     1570 Feb  3  2015 anaconda-ks.cfg
drwxr-xr-x 2 root root     4096 Feb  3  2015 Desktop
-rw-r--r-- 1 root root    59038 Feb  3  2015 install.log
-rw-r--r-- 1 root root     5266 Feb  3  2015 install.log.syslog
-rw-r--r-- 1 root root   908984 May 18 12:29 nginx-1.9.15.tar.gz
-rw-r--r-- 1 root root  2053336 May 18 18:12 pcre-8.38.tar.gz
-rw-r--r-- 1 root root 18207283 May 18 18:13 php-7.0.6.tar.gz
-rw-r--r-- 1 root root   148960 May 18 09:42 zabbix-2.2.1-1.el5.x86_64.rpm
-rw-r--r-- 1 root root   248051 May 18 09:41 zabbix-agent-2.2.1-1.el5.x86_64.rpm
-rw-r--r-- 1 root root    11296 May 18 09:33 zabbix-release-2.4-1.el6.noarch.rpm

实际上,上面的几个函数都是基于Popen()的封装(wrapper)。这些封装的目的在于让我们容易使用子进程。当我们想要更个性化我们的需求的时候,就要转向Popen类,该类生成的对象用来代表子进程。

与上面的封装不同,Popen对象创建后,主程序不会自动等待子进程完成。我们必须调用对象的wait()方法,父进程才会等待 (也就是阻塞block),举例:


import subprocess
child = subprocess.Popen(['ping','-n','4','blog.linuxeye.com'])
# child.wait()
print ('parent process')
结果:
从运行结果中看到,父进程在开启子进程之后并没有等待child的完成,而是直接运行print。
parent process

import
subprocess child = subprocess.Popen(['ping','-n','4','blog.linuxeye.com']) child.wait() print ('parent process')
结果:(先等待子进程完成) 正在 Ping blog.linuxeye.com [
121.40.145.83] 具有 32 字节的数据: 来自 121.40.145.83 的回复: 字节=32 时间=29ms TTL=52 来自 121.40.145.83 的回复: 字节=32 时间=33ms TTL=52 来自 121.40.145.83 的回复: 字节=32 时间=30ms TTL=52 来自 121.40.145.83 的回复: 字节=32 时间=32ms TTL=52 121.40.145.83 的 Ping 统计信息: 数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失), 往返行程的估计时间(以毫秒为单位): 最短 = 29ms,最长 = 33ms,平均 = 31ms parent process

在父进程等待的时候,还可以对子进程做其他的操作

child.poll() # 检查子进程状态
child.kill() # 终止子进程
child.send_signal() # 向子进程发送信号
child.terminate() # 终止子进程

子进程的标准输入、标准输出和标准错误如下属性分别表示:

child.stdin
child.stdout
child.stderr

可以在Popen()建立子进程的时候改变标准输入、标准输出和标准错误,并可以利用subprocess.PIPE将多个子进程的输入和输出连接在一起,构成管道(pipe),如下2个例子:

把输出放入到stdout中,然后从stdout中读出来
>>> child1 = subprocess.Popen(["ls","-l"], stdout=subprocess.PIPE) >>> print child1.stdout.read() total 21244 -rw------- 1 root root 1570 Feb 3 2015 anaconda-ks.cfg drwxr-xr-x 2 root root 4096 Feb 3 2015 Desktop -rw-r--r-- 1 root root 59038 Feb 3 2015 install.log -rw-r--r-- 1 root root 5266 Feb 3 2015 install.log.syslog -rw-r--r-- 1 root root 908984 May 18 12:29 nginx-1.9.15.tar.gz -rw-r--r-- 1 root root 2053336 May 18 18:12 pcre-8.38.tar.gz -rw-r--r-- 1 root root 18207283 May 18 18:13 php-7.0.6.tar.gz -rw-r--r-- 1 root root 148960 May 18 09:42 zabbix-2.2.1-1.el5.x86_64.rpm -rw-r--r-- 1 root root 248051 May 18 09:41 zabbix-agent-2.2.1-1.el5.x86_64.rpm -rw-r--r-- 1 root root 11296 May 18 09:33 zabbix-release-2.4-1.el6.noarch.rpm
>>> 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()
>>> print out
('root:x:0:0:root:/root:/bin/bash\n', None)


  >>> import subprocess
  >>> child1 = subprocess.Popen(["cat","/etc/passwd"], stdout=subprocess.PIPE)
  >>> child2 = subprocess.Popen(["grep","0:0"],stdin=child1.stdout, stdout=subprocess.PIPE)
  >>> print child2.stdout.read
  <built-in method read of file object at 0x2b5838884be8>
  >>> print child2.stdout.read()
  root:x:0:0:root:/root:/bin/bash

 

posted on 2016-06-03 17:23  Alex0425  阅读(177)  评论(0编辑  收藏  举报