python子进程模块subprocess详解

本贴最后更新于 3121 天前,其中的信息可能已经水流花落

属性

1.Popen.poll():用于检查子进程是否已经结束。设置并返回returncode属性。

2.Popen.wait():等待子进程结束。设置并返回returncode属性。

3.Popen.communicate(input=None):与子进程进行交互。向stdin发送数据,或从stdout和stderr中读取数据。可选参数input指定发送到子进程的参数。Communicate()返回一个元组:(stdoutdata, stderrdata)。注意:如果希望通过进程的stdin向其发送数据,在创建Popen对象的时候,参数stdin必须被设置为PIPE。同样,如果希望从stdout和stderr获取数据,必须将stdout和stderr设置为PIPE。

4.Popen.send_signal(signal):向子进程发送信号。

5.Popen.terminate():停止(stop)子进程。在windows平台下,该方法将调用Windows API TerminateProcess()来结束子进程。

6.Popen.kill():杀死子进程。

7.Popen.stdin:如果在创建Popen对象是,参数stdin被设置为PIPE,Popen.stdin将返回一个文件对象用于策子进程发送指令。否则返回None。

8.Popen.stdout:如果在创建Popen对象是,参数stdout被设置为PIPE,Popen.stdout将返回一个文件对象用于策子进程发送指令。否则返回None。

9.Popen.stderr:如果在创建Popen对象是,参数stdout被设置为PIPE,Popen.stdout将返回一个文件对象用于策子进程发送指令。否则返回None。

10.Popen.pid:获取子进程的进程ID。

11.Popen.returncode:获取进程的返回值。如果进程还没有结束,返回None。

12.subprocess.call(*popenargs, **kwargs):运行命令。该函数将一直等待到子进程运行结束,并返回进程的returncode。文章一开始的例子就演示了call函数。如果子进程不需要进行交互,就可以使用该函数来创建。

13.subprocess.check_call(*popenargs, **kwargs):与subprocess.call(*popenargs, **kwargs)功能一样,只是如果子进程返回的returncode不为0的话,将触发CalledProcessError异常。在异常对象中,包括进程的returncode信息。

 关于subprocess的安全性:

不像其他的popen函数,不会直接调用/bin/sh来解释命令,也就是说,命令中的每一个字符都会被安全地传递到子进程里。

一:用subprocess获取stdout和stderr

第一种方案:

import subprocess

p = subprocess.Popen(['tail','-10','/tmp/hosts.txt'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=False)

stdout,stderr = p.communicate()

print 'stdout : ',stdout

print 'stderr : ',stder

popen调用的时候会在父进程和子进程建立管道,然后我们可以把子进程的标准输出和错误输出都重定向到管道,然后从父进程取出。上面的communicate会一直阻塞,直到子进程跑完。这种方式是不能及时获取子程序的stdout和stderr。

第二种方案:

可以获取实时的输出信息

p = subprocess.Popen("/etc/service/tops-cmos/module/hadoop/test.sh", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

returncode = p.poll()

while returncode is None:

    line = p.stdout.readline()

    returncode = p.poll()

    line = line.strip()

    print line

print returncode

这里就是把错误输出重定向到PIPE对应的标准输出,也就是说现在stderr都stdout是一起的了,下面是一个while,poll回去不断查看子进程是否已经被终止,如果程序没有终止,就一直返回None,但是子进程终止了就返货状态码,甚至于调用多次poll都会返回状态码。上面的demo就是可以获取子进程的标准输出和标准错误输出。

二:使用subprocess的Popen函数执行系统命令

1、执行shell命令:

Popen函数指定shell=True即可,linux下参数executable将指定程序使用的shell,windows下无须指定。

示例1:

在windows下执行cd命令获取当前目录

p2 = Popen('cd',shell=True)

2、执行其他程序

3、指定子进程工作路径:

示例1:

使新建的子进程工作指定的工作目录之下:

import sys,os,subprocess,commands

from subprocess import Popen,PIPE

p2 = Popen('cd',shell=True,stdout=PIPE,cwd='E:\svnworking')

p2.wait()

print "当前目录:%s" %p2.stdout.read()

 

上述命令使用了cwd,该参数指定了子进程工作目录。这个参数很有用,有时涉及到相对路径的时候必须如果不指定cwd,则程序可能出错。

示例2:

a.py文件:

p2 = Popen('python c:\b.py',shell=True,stdout=PIPE) #在a.py运行脚本b.py

p2.wait()

print "当前目录:%s" %p2.stdout.read()

b.py文件:

f=open('test.txt','a') #注意这里使用了相对路径

f.close()

当a.py和b.py不在同一个目录的时候,运行a.py肯定报错(找不到指定的文件test.txt)。

原因:因为p2 = Popen('python c:\b.py',shell=True,stdout=PIPE') 创建的子进程与a.py在同一目录下工作,而该目录没有test.py。

解决方法:指定cwd参数。

4、获取Popen的返回值及输出

示例:

# -*- coding: UTF-8 -*-

#执行另外一个脚本

import sys,os,subprocess,commands

from subprocess import Popen,PIPE

p = Popen('python ' + path + '\getCurPath.py', stdout=PIPE, stderr=PIPE)

p.wait()

if(p.returncode == 0):

print "stdout:%s" %p.stdout.read()

 

三:subprocess的Popen函数的等待(wait()方法)

1. Popen对象创建后,主程序不会自动等待子进程完成。

我们必须调用对象的wait()方法,父进程才会等待 (也就是阻塞block):

    import subprocess

    child = subprocess.Popen(["ping","-c","5","www.google.com"])

    print("parent process")

从运行结果中看到,父进程在开启子进程之后并没有等待child的完成,而是直接运行print。

2. 对比等待的情况:

   import subprocess

   child = subprocess.Popen(["ping","-c","5","www.google.com"])

   child.wait()

   print("parent process")

此外,你还可以在父进程中对子进程进行其它操作,比如我们上面例子中的child对象:

child.poll()           # 检查子进程状态

child.kill()           # 终止子进程

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

child.terminate()      # 终止子进程

子进程的PID存储在child.pid

四:subprocess的Popen函数的标准输入、标准输出和标准错误

1. 可以在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)

subprocess.PIPE实际上为文本流提供一个缓存区。

child1的stdout将文本输出到缓存区,随后child2的stdin从该PIPE中将文本读取走。

child2的输出文本也被存放在PIPE中,直到communicate()方法从PIPE中读取出PIPE中的文本。

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

2. 还可以利用communicate()方法来使用PIPE给子进程输入:

    import subprocess

    child = subprocess.Popen(["cat"], stdin=subprocess.PIPE)

    child.communicate("vamei")

我们启动子进程之后,cat会等待输入,直到我们用communicate()输入"vamei"。

通过使用subprocess包,我们可以运行外部程序。这极大的拓展了Python的功能。

如果你已经了解了操作系统的某些应用,你可以从Python中直接调用该应用(而不是完全依赖Python),

并将应用的结果输出给Python,并让Python继续处理。

shell的功能(比如利用文本流连接各个应用),就可以在Python中实现。



 

  • Python

    Python 是一种面向对象、直译式电脑编程语言,具有近二十年的发展历史,成熟且稳定。它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务。它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用缩进来定义语句块。

    543 引用 • 672 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • 游戏

    沉迷游戏伤身,强撸灰飞烟灭。

    176 引用 • 815 回帖
  • App

    App(应用程序,Application 的缩写)一般指手机软件。

    91 引用 • 384 回帖
  • Spark

    Spark 是 UC Berkeley AMP lab 所开源的类 Hadoop MapReduce 的通用并行框架。Spark 拥有 Hadoop MapReduce 所具有的优点;但不同于 MapReduce 的是 Job 中间输出结果可以保存在内存中,从而不再需要读写 HDFS,因此 Spark 能更好地适用于数据挖掘与机器学习等需要迭代的 MapReduce 的算法。

    74 引用 • 46 回帖 • 552 关注
  • 架构

    我们平时所说的“架构”主要是指软件架构,这是有关软件整体结构与组件的抽象描述,用于指导软件系统各个方面的设计。另外还有“业务架构”、“网络架构”、“硬件架构”等细分领域。

    142 引用 • 442 回帖 • 1 关注
  • OpenStack

    OpenStack 是一个云操作系统,通过数据中心可控制大型的计算、存储、网络等资源池。所有的管理通过前端界面管理员就可以完成,同样也可以通过 Web 接口让最终用户部署资源。

    10 引用 • 4 关注
  • 工具

    子曰:“工欲善其事,必先利其器。”

    286 引用 • 729 回帖
  • 分享

    有什么新发现就分享给大家吧!

    248 引用 • 1792 回帖
  • 996
    13 引用 • 200 回帖 • 6 关注
  • 房星科技

    房星网,我们不和没有钱的程序员谈理想,我们要让程序员又有理想又有钱。我们有雄厚的房地产行业线下资源,遍布昆明全城的 100 家门店、四千地产经纪人是我们坚实的后盾。

    6 引用 • 141 回帖 • 585 关注
  • Notion

    Notion - The all-in-one workspace for your notes, tasks, wikis, and databases.

    6 引用 • 38 回帖
  • 设计模式

    设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。

    200 引用 • 120 回帖
  • WebComponents

    Web Components 是 W3C 定义的标准,它给了前端开发者扩展浏览器标签的能力,可以方便地定制可复用组件,更好的进行模块化开发,解放了前端开发者的生产力。

    1 引用 • 1 关注
  • SendCloud

    SendCloud 由搜狐武汉研发中心孵化的项目,是致力于为开发者提供高质量的触发邮件服务的云端邮件发送平台,为开发者提供便利的 API 接口来调用服务,让邮件准确迅速到达用户收件箱并获得强大的追踪数据。

    2 引用 • 8 回帖 • 483 关注
  • Sphinx

    Sphinx 是一个基于 SQL 的全文检索引擎,可以结合 MySQL、PostgreSQL 做全文搜索,它可以提供比数据库本身更专业的搜索功能,使得应用程序更容易实现专业化的全文检索。

    1 引用 • 211 关注
  • 新人

    让我们欢迎这对新人。哦,不好意思说错了,让我们欢迎这位新人!
    新手上路,请谨慎驾驶!

    52 引用 • 228 回帖
  • CloudFoundry

    Cloud Foundry 是 VMware 推出的业界第一个开源 PaaS 云平台,它支持多种框架、语言、运行时环境、云平台及应用服务,使开发人员能够在几秒钟内进行应用程序的部署和扩展,无需担心任何基础架构的问题。

    5 引用 • 18 回帖 • 167 关注
  • GitLab

    GitLab 是利用 Ruby 一个开源的版本管理系统,实现一个自托管的 Git 项目仓库,可通过 Web 界面操作公开或私有项目。

    46 引用 • 72 回帖
  • Google

    Google(Google Inc.,NASDAQ:GOOG)是一家美国上市公司(公有股份公司),于 1998 年 9 月 7 日以私有股份公司的形式创立,设计并管理一个互联网搜索引擎。Google 公司的总部称作“Googleplex”,它位于加利福尼亚山景城。Google 目前被公认为是全球规模最大的搜索引擎,它提供了简单易用的免费服务。不作恶(Don't be evil)是谷歌公司的一项非正式的公司口号。

    49 引用 • 192 回帖
  • Chrome

    Chrome 又称 Google 浏览器,是一个由谷歌公司开发的网页浏览器。该浏览器是基于其他开源软件所编写,包括 WebKit,目标是提升稳定性、速度和安全性,并创造出简单且有效率的使用者界面。

    62 引用 • 289 回帖 • 1 关注
  • 程序员

    程序员是从事程序开发、程序维护的专业人员。

    567 引用 • 3532 回帖
  • 开源

    Open Source, Open Mind, Open Sight, Open Future!

    408 引用 • 3574 回帖
  • Facebook

    Facebook 是一个联系朋友的社交工具。大家可以通过它和朋友、同事、同学以及周围的人保持互动交流,分享无限上传的图片,发布链接和视频,更可以增进对朋友的了解。

    4 引用 • 15 回帖 • 453 关注
  • InfluxDB

    InfluxDB 是一个开源的没有外部依赖的时间序列数据库。适用于记录度量,事件及实时分析。

    2 引用 • 72 关注
  • Mac

    Mac 是苹果公司自 1984 年起以“Macintosh”开始开发的个人消费型计算机,如:iMac、Mac mini、Macbook Air、Macbook Pro、Macbook、Mac Pro 等计算机。

    166 引用 • 595 回帖
  • golang

    Go 语言是 Google 推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发 Go,是因为过去 10 多年间软件开发的难度令人沮丧。Go 是谷歌 2009 发布的第二款编程语言。

    497 引用 • 1387 回帖 • 284 关注
  • ZooKeeper

    ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 HBase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

    59 引用 • 29 回帖 • 4 关注
  • Laravel

    Laravel 是一套简洁、优雅的 PHP Web 开发框架。它采用 MVC 设计,是一款崇尚开发效率的全栈框架。

    20 引用 • 23 回帖 • 721 关注