python子进程模块subprocess详解

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

属性

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

    541 引用 • 672 回帖

相关帖子

欢迎来到这里!

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

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

推荐标签 标签

  • Lute

    Lute 是一款结构化的 Markdown 引擎,支持 Go 和 JavaScript。

    25 引用 • 191 回帖 • 16 关注
  • flomo

    flomo 是新一代 「卡片笔记」 ,专注在碎片化时代,促进你的记录,帮你积累更多知识资产。

    5 引用 • 107 回帖
  • etcd

    etcd 是一个分布式、高可用的 key-value 数据存储,专门用于在分布式系统中保存关键数据。

    5 引用 • 26 回帖 • 527 关注
  • RabbitMQ

    RabbitMQ 是一个开源的 AMQP 实现,服务器端用 Erlang 语言编写,支持多种语言客户端,如:Python、Ruby、.NET、Java、C、PHP、ActionScript 等。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。

    49 引用 • 60 回帖 • 363 关注
  • 资讯

    资讯是用户因为及时地获得它并利用它而能够在相对短的时间内给自己带来价值的信息,资讯有时效性和地域性。

    55 引用 • 85 回帖
  • 锤子科技

    锤子科技(Smartisan)成立于 2012 年 5 月,是一家制造移动互联网终端设备的公司,公司的使命是用完美主义的工匠精神,打造用户体验一流的数码消费类产品(智能手机为主),改善人们的生活质量。

    4 引用 • 31 回帖 • 3 关注
  • PWA

    PWA(Progressive Web App)是 Google 在 2015 年提出、2016 年 6 月开始推广的项目。它结合了一系列现代 Web 技术,在网页应用中实现和原生应用相近的用户体验。

    14 引用 • 69 回帖 • 152 关注
  • Webswing

    Webswing 是一个能将任何 Swing 应用通过纯 HTML5 运行在浏览器中的 Web 服务器,详细介绍请看 将 Java Swing 应用变成 Web 应用

    1 引用 • 15 回帖 • 624 关注
  • 新人

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

    52 引用 • 228 回帖 • 1 关注
  • IDEA

    IDEA 全称 IntelliJ IDEA,是一款 Java 语言开发的集成环境,在业界被公认为最好的 Java 开发工具之一。IDEA 是 JetBrains 公司的产品,这家公司总部位于捷克共和国的首都布拉格,开发人员以严谨著称的东欧程序员为主。

    180 引用 • 400 回帖
  • Bug

    Bug 本意是指臭虫、缺陷、损坏、犯贫、窃听器、小虫等。现在人们把在程序中一些缺陷或问题统称为 bug(漏洞)。

    75 引用 • 1737 回帖
  • Caddy

    Caddy 是一款默认自动启用 HTTPS 的 HTTP/2 Web 服务器。

    12 引用 • 54 回帖 • 164 关注
  • CongSec

    本标签主要用于分享网络空间安全专业的学习笔记

    1 引用 • 1 回帖 • 6 关注
  • jsoup

    jsoup 是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址、HTML 文本内容。它提供了一套非常省力的 API,可通过 DOM,CSS 以及类似于 jQuery 的操作方法来取出和操作数据。

    6 引用 • 1 回帖 • 481 关注
  • 笔记

    好记性不如烂笔头。

    308 引用 • 793 回帖
  • 一些有用的避坑指南。

    69 引用 • 93 回帖 • 1 关注
  • ZooKeeper

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

    59 引用 • 29 回帖 • 7 关注
  • 心情

    心是产生任何想法的源泉,心本体会陷入到对自己本体不能理解的状态中,因为心能产生任何想法,不能分出对错,不能分出自己。

    59 引用 • 369 回帖 • 1 关注
  • 旅游

    希望你我能在旅途中找到人生的下一站。

    90 引用 • 899 回帖 • 1 关注
  • 架构

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

    142 引用 • 442 回帖 • 2 关注
  • 快应用

    快应用 是基于手机硬件平台的新型应用形态;标准是由主流手机厂商组成的快应用联盟联合制定;快应用标准的诞生将在研发接口、能力接入、开发者服务等层面建设标准平台;以平台化的生态模式对个人开发者和企业开发者全品类开放。

    15 引用 • 127 回帖
  • OkHttp

    OkHttp 是一款 HTTP & HTTP/2 客户端库,专为 Android 和 Java 应用打造。

    16 引用 • 6 回帖 • 61 关注
  • BAE

    百度应用引擎(Baidu App Engine)提供了 PHP、Java、Python 的执行环境,以及云存储、消息服务、云数据库等全面的云服务。它可以让开发者实现自动地部署和管理应用,并且提供动态扩容和负载均衡的运行环境,让开发者不用考虑高成本的运维工作,只需专注于业务逻辑,大大降低了开发者学习和迁移的成本。

    19 引用 • 75 回帖 • 634 关注
  • SendCloud

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

    2 引用 • 8 回帖 • 480 关注
  • 机器学习

    机器学习(Machine Learning)是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。

    83 引用 • 37 回帖
  • sts
    2 引用 • 2 回帖 • 196 关注
  • 运维

    互联网运维工作,以服务为中心,以稳定、安全、高效为三个基本点,确保公司的互联网业务能够 7×24 小时为用户提供高质量的服务。

    149 引用 • 257 回帖