Python标准库06之子进程 (subprocess包) 详解

这里的内容以Linux进程基础和Linux文本流为基础。subprocess包主要功能是执行外部的命令和程序。比如说,我需要使用wget下载文件。我在Python中调用wget程序。从这个意义上来说,subprocess的功能与shell类似。

subprocess以及常用的封装函数

当我们运行python的时候,我们都是在创建并运行一个进程。正如我们在Linux进程基础中介绍的那样,一个进程可以fork一个子进程,并让这个子进程exec另外一个程序。在Python中,我们通过标准库中的subprocess包来fork一个子进程,并运行一个外部的程序(fork,exec见Linux进程基础)。

subprocess包中定义有数个创建子进程的函数,这些函数分别以不同的方式创建子进程,所以我们可以根据需要来从中选取一个使用。另外subprocess还提供了一些管理标准流(standard stream)和管道(pipe)的工具,从而在进程间使用文本通信。

使用subprocess包中的函数创建子进程的时候,要注意:

1) 在创建子进程之后,父进程是否暂停,并等待子进程运行。

2) 函数返回什么

3) 当returncode不为0时,父进程如何处理。

subprocess.call()

父进程等待子进程完成

返回退出信息(returncode,相当于exit code,见Linux进程基础)

subprocess.check_call()

父进程等待子进程完成

返回0

检查退出信息,如果returncode不为0,则举出错误subprocess.CalledProcessError,该对象包含有returncode属性,可用try...except...来检查(见Python错误处理)。

subprocess.check_output()

父进程等待子进程完成

返回子进程向标准输出的输出结果

检查退出信息,如果returncode不为0,则举出错误subprocess.CalledProcessError,该对象包含有returncode属性和output属性,output属性为标准输出的输出结果,可用try...except...来检查。

这三个函数的使用方法相类似,我们以subprocess.call()来说明:

import subprocess
rc = subprocess.call(["ls","-l"])

我们将程序名(ls)和所带的参数(-l)一起放在一个表中传递给subprocess.call()

可以通过一个shell来解释一整个字符串:

import subprocess
out = subprocess.call("ls -l", shell=True)
out = subprocess.call("cd ..", shell=True)

我们使用了shell=True这个参数。这个时候,我们使用一整个字符串,而不是一个表来运行子进程。Python将先运行一个shell,再用这个shell来解释这整个字符串。

shell命令中有一些是shell的内建命令,这些命令必须通过shell运行,$cd。shell=True允许我们运行这样一些命令。

Popen()

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

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

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

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

对比等待的情况:

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

 子进程的文本流控制

(沿用child子进程) 子进程的标准输入,标准输出和标准错误也可以通过如下属性表示:

  • child.stdin
  • child.stdout
  • child.stderr

我们可以在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对象的一个方法,该方法会阻塞父进程,直到子进程完成。

我们还可以利用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中实现。

总结

subprocess.call, subprocess.check_call(), subprocess.check_output()

subprocess.Popen(), subprocess.PIPE

Popen.wait(), Popen.communicate()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Python的subprocess模块总结

    subprocess意在替代其他几个老的模块或者函数,比如:os.system os.spawn* os.popen* popen2.* commands.* subprocess最简单的用法就是调用shell命令了,另外也可以调用程序,并且可以通过stdout,stdin和stderr进行交互. subprocess的主类 复制代码 代码如下: subprocess.Popen(       args,       bufsize=0,       executable=None,      

  • Python中subprocess的简单使用示例

    在c语言中,一个进程可以fork出一个子进程,并让这个子进程exec一个新的命令.在python中,我们通过标准库的subprocess包来fork一个子进程,并在子进程中运行一个新的程序. subprocess包中有数个创建子进程的函数,这些函数分别以不同的方式创建子进程,所以我们可以根据需要来从中选取一个使用.另外subprocess还提供了一些管理标准流(standard stream)和管道(pipe)的工具,从而在进程间使用文本通信. 使用subprocess包中的函数创建子进程的时候

  • Python subprocess模块学习总结

    一.subprocess以及常用的封装函数运行python的时候,我们都是在创建并运行一个进程.像Linux进程那样,一个进程可以fork一个子进程,并让这个子进程exec另外一个程序.在Python中,我们通过标准库中的subprocess包来fork一个子进程,并运行一个外部的程序.subprocess包中定义有数个创建子进程的函数,这些函数分别以不同的方式创建子进程,所以我们可以根据需要来从中选取一个使用.另外subprocess还提供了一些管理标准流(standard stream)和管

  • Python 创建子进程模块subprocess详解

    最近,我们老大要我写一个守护者程序,对服务器进程进行守护.如果服务器不幸挂掉了,守护者能即时的重启应用程序.上网Google了一下,发现Python有很几个模块都可以创建进程.最终我选择使用subprocess模块,因为在Python手册中有这样一段话: This module intends to replace several other, older modules and functions, such as: os.system.os.spawn*.os.popen*.popen2.*

  • python进程类subprocess的一些操作方法例子

    subprocess.Popen用来创建子进程. 1)Popen启动新的进程与父进程并行执行,默认父进程不等待新进程结束. 复制代码 代码如下: def TestPopen():   import subprocess   p=subprocess.Popen("dir",shell=True)   for i in range(250) :     print ("other things") 2)p.wait函数使得父进程等待新创建的进程运行结束,然后再继续父进

  • Python中subprocess模块用法实例详解

    本文实例讲述了Python中subprocess模块用法.分享给大家供大家参考.具体如下: 执行命令: >>> subprocess.call(["ls", "-l"]) 0 >>> subprocess.call("exit 1", shell=True) 1 测试调用系统中cmd命令,显示命令执行的结果: x=subprocess.check_output(["echo", "

  • Python下的subprocess模块的入门指引

    在熟悉了Qt的QProcess以后,再回头来看python的subprocess总算不觉得像以前那么恐怖了. 和QProcess一样,subprocess的目标是启动一个新的进程并与之进行通讯. subprocess.Popen 这个模块主要就提供一个类Popen: class subprocess.Popen( args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, clo

  • python subprocess 杀掉全部派生的子进程方法

    下面就是今天下午的研究成果. 发布系统需要响应用户的中断请求,需要在GET方法中杀掉由subprocess派生的子进程,刚开始直接用os.kill 发现子进程的子进程无法kill,谷歌了一些,发现kill可以干掉进程组,于是测试,但是默认情况下,subprocess派生的进程组和主程序,也就是我的web.py进程是在一个进程组里的,这要是kill了,那就调的了. 继续翻google,看subprocess的document时发现这个变量: subprocess.CREATE_NEW_PROCES

  • Python标准库06之子进程 (subprocess包) 详解

    这里的内容以Linux进程基础和Linux文本流为基础.subprocess包主要功能是执行外部的命令和程序.比如说,我需要使用wget下载文件.我在Python中调用wget程序.从这个意义上来说,subprocess的功能与shell类似. subprocess以及常用的封装函数 当我们运行python的时候,我们都是在创建并运行一个进程.正如我们在Linux进程基础中介绍的那样,一个进程可以fork一个子进程,并让这个子进程exec另外一个程序.在Python中,我们通过标准库中的subp

  • python标准库压缩包模块zipfile和tarfile详解(常用标准库)

    目录 常用的标准库 zip格式 ZipFile参数说明 操作含义 压缩方法 常用方法 tar包 和 gz.bz2.xz格式 删除压缩包中的文件 常用的标准库 在我们常用的系统windows和Linux系统中有很多支持的压缩包格式,包括但不限于以下种类:rar.zip.tar,以下的标准库的作用就是用于压缩解压缩其中一些格式的压缩包. zip格式 import zipfile zipfile模块操作压缩包使用ZipFile类进行操作,使用方法和open的使用方法很相似,也是使用r.w.x.a四种操

  • Python标准库之Math,Random模块使用详解

    目录 数学模块 ceil -- 上取整 floor -- 下取整 四舍五入 pow -- 幂运算 sqrt -- 开平方运算 fabs -- 绝对值 modf -- 拆分整数小数 copysign -- 正负拷贝 fsum -- 序列和 pi -- 圆周率常数 factorial -- 因数 随机模块 random -- 获取 0~~1 之间的小数 randrange -- 获取指定范围内的整数 randint -- 获取指定范围整数 uniform -- 获取指定范围内随机小数(左闭右开) c

  • Python标准库uuid模块(生成唯一标识)详解

    目录 UUID格式组成 Python 中的uuid 模块 uuid1() 中的getnode() UUID实际应用 UUID 的劣势 参考资料: 总结 UUID (Universally Unique Identifier,通用唯一标识)是一个128位的用于计算机系统中以识别信息的数目,虽然生成UUID的概率不为零,但是无限接近零,因此可以忽略不记,如此一来,每个人都可以建立不与其他人冲突的UUID. UUID格式组成 规范的文本中,UUID的十六个八位字节标识位32个十六进制(基数16)数字,

  • Python标准库中的logging用法示例详解

    目录 1.logging的介绍 2.简单用法示例 3.日志级别 4.打印格式的各个参数 5.日志输出到指定文件 6.日志回滚(按照文件大小滚动) 7.日志回滚(按照时间滚动) 1.logging的介绍 logging是Python标准库中记录常用的记录日志库,通过logging模块存储各种格式的日志,主要用于输出运行日志,可以设置输出日志的等级.日志保存路径.日志文件回滚等. 2.简单用法示例 首先创建一个logger.py的文件,其里面的代码如下所示: import logging # 1.创

  • Python图像处理库PIL的ImageDraw模块介绍详解

    ImageDraw模块提供了图像对象的简单2D绘制.用户可以使用这个模块创建新的图像,注释或润饰已存在图像,为web应用实时产生各种图形. PIL中一个更高级绘图库见The aggdraw Module 一.ImageDraw模块的概念 1.  Coordinates 绘图接口使用和PIL一样的坐标系统,即(0,0)为左上角. 2.  Colours 为了指定颜色,用户可以使用数字或者元组,对应用户使用函数Image.new或者Image.putpixel.对于模式为"1","

  • Python图像处理库PIL的ImageGrab模块介绍详解

    ImageGrab模块用于将当前屏幕的内容或者剪贴板上的内容拷贝到PIL图像内存. 当前版本只支持windows系统. 一.ImageGrab模块的函数 1.  Grab 定义:ImageGrab.grab()⇒ image ImageGrab.grab(bbox) ⇒ image 含义:(New in 1.1.3)抓取当前屏幕的快照,返回一个模式为"RGB"的图像.参数边界框用于限制只拷贝当前屏幕的一部分区域. 例子: >>> from PIL importImag

  • Python黑魔法库安装及操作字典示例详解

    目录 1. 安装方法 2. 简单示例 3. 兼容字典的所有操作 4. 设置返回默认值 5. 工厂函数自动创建key 6. 序列化的支持 7. 说说局限性 本篇文章收录于<Python黑魔法手册>v3.0 第七章,手册完整版在线阅读地址:Python黑魔法手册 3.0 文档 字典是 Python 中基础的数据结构之一,字典的使用,可以说是非常的简单粗暴,但即便是这样一个与世无争的数据结构,仍然有很多人 "用不惯它" . 也许你并不觉得,但我相信,你看了这篇文章后,一定会和我一

  • Python Asyncio库之asyncio.task常用函数详解

    目录 前记 0.基础 1.休眠--asyncio.sleep 2.屏蔽取消--asyncio.shield 3.超时--asyncio.wait_for 4.简单的等待--wait 5.迭代可等待对象的完成--asyncio.as_completed 前记 Asyncio在经过一段时间的发展以及获取Curio等第三方库的经验来提供更多的功能,目前高级功能也基本完善,但是相对于其他语言,Python的Asyncio高级功能还是不够的,但好在Asyncio的低级API也比较完善,开发者可以通过参考A

  • Python Asyncio 库之同步原语常用函数详解

    目录 前记 0.基础 1.Lock 2.Event 4.Condition 5.Semaphore 前记 Asyncio的同步原语可以简化我们编写资源竞争的代码和规避资源竞争导致的Bug的出现. 但是由于协程的特性,在大部分业务代码中并不需要去考虑资源竞争的出现,导致Asyncio同步原语被使用的频率比较低,但是如果想基于Asyncio编写框架则需要学习同步原语的使用. 0.基础 同步原语都是适用于某些条件下对某个资源的争夺,在代码中大部分的资源都是属于一个代码块,而Python对于代码块的管理

随机推荐