【Python】 子进程创建与使用subprocess

subprocess

*****本文参考了Vamei大神的http://www.cnblogs.com/vamei/archive/2012/09/23/2698014.html  

 运用subprocess包可以在运行python的进程下进一步开启一个子进程,创建子进程要注意

    1. 父进程是否暂停

    2.创建出的子进程返回了什么

    3.执行出错,即返回的code不是0的时候应该如何处理

  subprocess包提供了三个开启子进程的方法,subprocess.call() , subprocess.check_call() , subprocess.check_output(),给三者传递命令字符串作为参数。可以用([‘ping‘,‘www.baidu.com‘,‘-c‘,‘3‘])这种列表的形式,同时也可以是("ping www.baidu.com -c 3") 这种形式。在开启子进程的时候,可以加上shell=True的参数来让python开启一个shell,通过shell来解释获得的命令。一般在windows下运行的程序最好都把shell=True加上,这样才能顺利地执行dos命令,但是linux下似乎不加也没啥关系。因为linux下未指明用shell执行的话会调用/bin/sh来执行,问题不大,但是dos下系统不会默认用cmd.exe来执行命令,所以要加上shell=True。

  subprocess.call ; subprocess.check_call ; subprocess.check_output  这三者的区别在于,返回的值分别是,子进程的执行返回码;若返回码是0则返回0,否则出错的话raise起CalledProcessError,可以用except处理之;若返回码是0则返回子进程向stdout输出的结果,否则也raise起CalledProcessError。另外,这三个方法都是让父进程挂起等待的,在子进程结束之前,父进程不会继续往下运行。

  另外从本质上讲,上述三个方法都是对subprocess.Popen方法的一个包装,Popen开启的子进程是不会让父进程等待其完成的,除非调用了wait()方法:

child = subprocess.Popen("...",shell=True)
print "Hello"
"""
很可能hello在子进程的输出之前就被打印出来了,因为父进程不等child子进程运行完
"""

child = subprocess.Popen("...",shell=True)
child.wait()
print "Hello"
"""
这就不一样,父进程一定会等子进程运行完,给出完整的结果之后再继续往下执行。相当于wait函数挂起了父进程。
"""

  此外,上面代码里的child这个对象还有其他的一些方法:

    child.poll()  返回子进程运行状态,主要是两种结果,None代表尚未运行,而一个返回码则代表已经运行完成并且是成功或失败了

    child.kill()  强行终止子进程

    child.send_signal(...)  向子进程发送一个信号(具体信号是以什么方式表示不清楚,还待研究)

    child.terminate()  终止子进程

    child.pid  子进程的pid

    child.stdin/stdout/stderr    子进程的标准输入流,标准输出和标准错误输出,都是类文件对象

■  文本流控制

  每个子进程对象都有stdin/stdout/stderr三个对象,而在Popen开启子进程的时候,可以设置这三个对象。比如

child1 = subprocess.Popen("cmd1",shell=True, stdout=subprocess.PIPE)
‘‘‘
child1的stdout被设置成管道,可以把它理解成一个第三方托管机构,
因为不设置的话child1的stdout的内容就直接被打印到父进程的stdout里了,
设置成管道之后内容被导入了PIPEという名の第三方托管机构里
‘‘‘
child2 = subprocess.Popen("cmd2",shell=True,stdin=child1.stdout,stdout=subprocess.PIPE)
‘‘‘
把child2的stdin设置成了child1的stdout,也就是之前那个第三方机构,这么一来就实现了两个子进程之间的数据通信了。而把child2的stdout也设置成第三方,是因为不想让child2的输出就直接这么输出到父进程的stdout里,而要对它做一些处理
‘‘‘
stdout,tmp = child2.communicate()
‘‘‘
因为child2的输出不用再转给个child3去处理,就用communicate方法把第三方机构那里的数据取出来放进一个变量里。注意,这里的stdout已经是个str对象了,communicate出来的都是字符串了communicate方法自带wait功能,会让父进程挂起等待所有子进程结束communicate会返回一个元组,但是像在这个例子中没有设置stderr=PIPE,所以元组中的第二项原本属于stderr的值的地方的tmp的值是None,如果设置了其为PIPE,由于没有错误信息tmp是""。这点是有区别的。
‘‘‘
print "We have result:\n%s"%(stdout)    #代表了把stdout做一些处理后再输出

  实际上,我一般都是这么干的:

import subprocess

p = subprocess.Popen("CMD",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
stdout,stderr = p.communicate()
if stderr != "":
    print "ERROR:"+stderr
else:
    print "RESULT:"+stdout
时间: 2024-10-25 22:19:22

【Python】 子进程创建与使用subprocess的相关文章

python子进程模块subprocess详解与应用实例 之三

二.应用实例解析 2.1 subprocess模块的使用 1. subprocess.call >>> subprocess.call(["ls", "-l"])  0  >>> subprocess.call("exit 1", shell=True)  1 2. 调用系统中cmd命令,显示命令执行的结果: x=subprocess.check_output(["echo", "

python子进程模块subprocess详解

属性 1.Popen.poll():用于检查子进程是否已经结束.设置并返回returncode属性. 2.Popen.wait():等待子进程结束.设置并返回returncode属性. 3.Popen.communicate(input=None):与子进程进行交互.向stdin发送数据,或从stdout和stderr中读取数据.可选参数input指定发送到子进程的参数.Communicate()返回一个元组:(stdoutdata, stderrdata).注意:如果希望通过进程的stdin向

python学习--创建模块

昨天做了python客户端和服务器端通信,并把接收到的信息写到数据库,因为对数据库进行操作是个经常调用的行为,所以我想把调用数据库的操作写成一个module来给其它python程序调用,所以将昨天的服务器端程序拆分为两个文件: 1.主程序python.py #!/usr/bin/env python import socket import json import connmysql s = socket.socket(socket.AF_INET,socket.SOCK_STREAM,0) h

Python数组创建中的这些坑,你造吗?

本文和大家分享的主要是python 中创建数组过程中的一些坑,一起来看看吧,希望对大家 学习python 有所帮助. 1.问题的引出 在做leetcode 的题目时,遇到了一个求数组中出现次数最多的 k 个元素的题,参照答案的思路,首先利用一个 dict 记录所有元素出现的次数, key:value 中的 key 表示元素, value 表示元素出现的次数,随后根据元素出现的次数将元素放入对应的桶中,桶是一个二维数组,桶中第一个元素保存出现次数为 0 的元素,桶中第二个元素保存出现次数为 1 的

python——type()创建类

今天我算是长知识了,我是一个python菜鸟,以前一直认为type(A)可以返回A的类型,但是不知道type还可以用于创建class,这篇经验就是介绍一下如何用type()创建一个类,以及如何设置该类的属性. 我们使用type创建一个空类:只有一个名字,其他什么都没有,它的参数格式是:type(class_name,bases,dic) 我们用type来查看一下我们创建的cls的类型: 查看cls的名称 假如我们用比较熟悉的继承的方式来创建一个类,它跟cls是一样的: 当然,我们可以通过参数di

Python 动态创建函数【转】

知乎上也有相似的问题 偶然碰到一个问题,初想是通过动态创建Python函数的方式来解决,于是调研了动态创建Python函数的方法. 定义lambda函数 在Python中定义lambda函数的写法很简单, func = lambda: "foobar" 可以认为lambda函数是最常用的一种方式. 定义局部函数 Python中函数可以在代码块中进行定义,比如decorator就是通过这种方式实现的, def decorator(func): def _(*args, **kwargs)

cocos2d-x使用python脚本创建项目的简单方法

本文有CC原创.转载请注明地址:http://blog.csdn.net/oktears/article/details/13297003 在cocos2d-x2.1.4以上的版本号中.取消了使用vs模版创建项目的方法,開始使用python脚本创建项目,使用python创建项目须要在命令行敲非常多指令,比較麻烦. 我把这些命令组合在一起,放在了一个批处理文件里.直接双击打开批处理文件就能够通过几个简单的指令来创建项目. 第一步: 新建一个txt文件.将以下这段代码拷贝进去,保存文件.将文件名称改

Python PIL创建文字图片

PIL库中包含了很多模块,恰当地利用这些模块可以做许多图像处理方面的工作. 下面是我用来生成字母或字符串测试图片而写的类及测试代码. 主要用到的模块: PIL.Image,PIL.ImageDraw,PIL.ImageFont PIL.Image用来生成一个空的图片,ImageDraw用来在空图片上画图及写字符,ImageFont则是创建需要使用到的字体 #-*- coding:gb2312 -*- from PIL import Image,ImageDraw,ImageFont,ImageO

Python之创建tuple和“可变”的tuple

Python之创建tuple tuple是另一种有序的列表,中文翻译为" 元组 ".tuple 和 list 非常类似,但是,tuple一旦创建完毕,就不能修改了. 同样是表示班里同学的名称,用tuple表示如下: >>> t = ('Adam', 'Lisa', 'Bart') 创建tuple和创建list唯一不同之处是用( )替代了[ ]. 现在,这个 t 就不能改变了,tuple没有 append()方法,也没有insert()和pop()方法.所以,新同学没法