subprocess是用于启动进程,并与进程通信的模块。

·格式

该模块定义了一个Popen类:

class Popen(args, bufsize=0, executable=None,stdin=None, stdout=None, stderr=None,preexec_fn=None, close_fds=False, shell=False,cwd=None, env=None, universal_newlines=False,startupinfo=None, creationflags=0):

参数释义:

-args  应该是字符串或程序参数序列,要执行的程序通常是args序列或字符串中的第一项,但可以使用
executable参数显式设置。在UNIX 上,当 shell=False(默认), 类Popen 用 os.execvp() 来执行子程序,args通常应该是
一个序列,如果args是一个字符串,它也会被视为只有一个元素的序列。在UNIX 上,当 shell=True,如果 args 是字符串,它将作为命令行字符串通过shell 执行;如果是
一个序列,它的第一项将作为命令行字符串,其他项将被视为附加的shell参数。在 Windows 上,类Popen 用 CreateProcess() 来执行子程序,它以字符串作为参数。 如果args是一个序列,它将使用 list2cmdline 方法转换为字符串。需要注意的是,并非所有MS
Windows应用程序都以相同的方式解释命令行,list2cmdline 是为使用与MS C运行规则相同的应用程序而设
计的。- bufsize 如果被赋值,值将作为内建函数 open() 的参数,0意味着无缓冲,1就是行缓冲,任何其他正值
意味着使用与该值大小接近的缓冲区。负bufsize意味着使用系统默认值,这通常意味着完全缓冲。 bufsize
的默认值为0(无缓冲)。- stdin, stdout and stderr 分别代表子程序的标准输入,标准输出,标准错误输出的文件句柄。有效值为PIPE、现有文件描述符(正整数)、现有文件对象和None。若赋值为PIPE ,就会为子程序创
建新管道 ;若为None,不会发生重定向,子程序的文件句柄将从父程序继承。另外,stderr可以是STDOUT,这表明子程序的错误数据可以被获得并发送到stdout输出。-  preexec_fn 如果preexec_fn设置为可调用对象,则在执行子进程之前,将在子进程中调用此对象。- close_fds 若为true,则在执行子进程之前将关闭除0,1和2之外的所有文件描述符。- shell 若为true,则将通过shell执行指定的命令。- cwd 若不是None,在执行子进程之前,当前目录将更改为cwd。- env 若不是None,它将为新进程指定环境变量。- universal_newlines 文件对象stdout和stderr作为文本文件打开,但可以通过 '\n' (Unix), '\r'
(Mac), '\r\n' (Win)断行。所有这些外部表示都被Python程序视为'\n'。注意:仅当Python使用通用换行
支持(默认)构建时,此功能才可用。注意这些特征只在python支持通用换行的时候有效(默认支持)。此外,communication() 方法不会更新文件对象stdout,stdin和stderr的换行属性。- startupinfo, creationflags 如果给定,将传递给底层的 CreateProcess() 函数。它可以指定主窗口
的外观和新进程的优先级等内容。(仅限Windows)subprocess.startupinfo 详解网址:http://www.programcreek.com/python/example/5376/subprocess.STARTUPINFO

该模块还定义了两个快捷功能:

call(*args, **kwargs):

使用参数运行命令。等待命令完成,然后返回returncode属性。

参数与Popen构造函数相同。例:

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

··异常

在新程序开始执行之前,子进程中引发的异常将在父进程中重新引发。此外,异常对象将有一个名为'child_traceback'的额外属性,该属性是一个包含来自子进程视点的回溯信息的字符串。

引发的最常见异常是OSError。例如,在尝试执行不存在的文件时会发生这种情况。应用程序应当对OSErrors作出处理。

如果使用无效参数调用Popen,则会引发ValueError。

··安全性

与其他一些 popen 函数不同,此实现永远不会隐式调用/bin/sh。这意味着所有字符(包括shell元字符)都可以安全地传递给子进程。

··Popen 对象

Popen类的实例具有以下方法:

Popen.poll():

检查子进程是否已终止。终止则返回returncode属性;否则,返回None。

Popen.wait(timeout=None):

等待子进程终止,返回returncode属性。

如果进程在超时秒后没有终止,则引发 TimeoutExpired 异常。捕获此异常并重试等待将会更安全。

注意:当使用stdout = PIPE或stderr = PIPE,并且子进程生成太多输出以致于阻止了等待OS管道缓冲区接受更多数据时,将导致死锁。使用管道时可以使用 Popen.communicate() 来避免这种情况。

注意:该功能使用忙循环(非阻塞呼叫和短暂睡眠)实现。使用asyncio模块进行异步等待:请参阅asyncio.create_subprocess_exec。

在Python3.3中添加了timeout参数

从Python3.4开始不推荐使用endtime参数。这是无意中暴露在3.3中,但没有记录,因为它是私人内部使用。请改用timeout 。

Popen.communicate(input=Nonetimeout=None):

与进程交互:将数据发送到stdin。从stdout和stderr读取数据,直到达到文件结尾。等待进程终止。可选的input参数应该是要发送到子进程的数据,如果没有数据需要发送给子进程,则设为None。如果在文本(text)模式下打开流,则input参数必须是字符串(string);否则,它必须是字节(bytes)。

communic()返回一个 tuple(stdout_data, stderr_data) 。如果在文本模式下打开流,则数据将是字符串;否则,是字节。

注意:如果要将数据发送到进程的stdin,则需要使用stdin = PIPE创建Popen对象。同样,要在结果元组(tuple)中获取除None之外的任何内容,还需要设置stdout = PIPE and/or stderr = PIPE。

如果进程在超时(timeout)秒后没有终止,则会引发TimeoutExpired异常。捕获此异常并重试通信不会丢失任何输出。

如果超时到期,则子进程不会被终止,因此为了正确清理,行为良好的应用程序应该终止子进程并完成通信:

proc = subprocess.Popen(...)
try:outs, errs = proc.communicate(timeout=15)
except TimeoutExpired:proc.kill()outs, errs = proc.communicate()

注意:读取的数据缓冲在内存中,因此如果数据大小很大或不受限制,请不要使用此方法。

在Python3.3中添加了timeout参数

Popen.send_signal(signal):

向子进程发送signal信号。

注意:在 Windows 上,SIGTERM和terminate() 的作用相同。可以将 CTRL_C_EVENTCTRL_BREAK_EVENT 发送到使用 creationflags 参数启动的进程,该参数包括 CREATE_NEW_PROCESS_GROUP 。

Popen.terminate():

终止(stop)子进程。在Posix OSs上,该方法将SIGTERM发送给子进程。在Windows上,调用Win32 API函数TerminateProcess() 来停止子进程。

Popen.kill():

杀死子进程。在Posix OSs上,该方法将 SIGKILL 发送给子进程。在Windows上,kill() 和terminate() 的作用相同。

还提供以下属性:

Popen.args:

args参数传递给Popen - 程序参数序列或单个字符串。

Python3.3中的新功能。

Popen.stdin:

如果stdin参数是PIPE,则此属性是open() 返回的可写流对象。如果指定了encoding或errors参数或者universal_newlines参数为True,则流是文本流,否则它是字节流。如果stdin参数不是PIPE,则此属性为None。

   obj.stdin.write(" args ")

Popen.stdout:

如果stdout参数是PIPE,则此属性是open() 返回的可读流对象。从流中读取提供子进程的输出。如果指定了encoding或errors参数或者universal_newlines参数为True,则流是文本流,否则它是字节流。如果stdout参数不是PIPE,则此属性为None。

   obj.stdout.read() 

Popen.stderr:

如果stderr参数是PIPE,则此属性是open() 返回的可读流对象。从流中读取提供子进程的错误输出。如果指定了encoding或errors参数或者universal_newlines参数为True,则流是文本流,否则它是字节流。如果stderr参数不是PIPE,则此属性为None。

警告:使用 communic() 而不是 .stdin.write,.stdout.read 或 .stderr.read 来避免由于任何其他OS管道缓冲区填满和阻止子进程而导致的死锁。

Popen.pid:

子进程的进程ID。

注意:如果将shell参数设置为True,则这是生成的shell的进程ID。

Popen.returncode:

子进程返回码,由poll() 和wait() 设置(间接通过communic())。 None 表示该进程尚未终止,负值 -N 表示子进程被信号 N 终止(仅限POSIX)。

  • returncode=0 表示执行成功
  • returncode=127 表示语句为空串
  • returncode=17 表示找不到表
  • returncode=64 表示缺失关键字
  • returncode=41 表示查询的字段不存在

例如:

import os
import shlex
import signal
import subprocessshell_cmd = 'ping www.baidu.com'
cmd = shlex.split(shell_cmd)
p = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
# ***CTRL_C信号***
# os.kill(p.pid, signal.CTRL_C_EVENT)
# p.send_signal(signal.CTRL_C_EVENT)
# ***SIGTERM信号***
# p.send_signal(signal.SIGTERM)
# p.terminate()
# p.kill()
while p.poll() is None:  # 当子进程未终止line = p.stdout.readline().decode('gbk').strip()print(line)
if p.returncode == 0:print('Subprogram success')
else:print('Subprogram failed')

·用 subprocess 模块替换旧函数

在本节中,“a ==> b”表示a可以被b替代。

注意:如果找不到执行的程序,则本节中的所有函数都会或多或少的调用失败。此模块引发OSError异常。

在以下示例中,我们假设 subprocess 模块使用 from subprocess import * 导入。

··替换/bin/sh shell反引号

output=`mycmd myarg`
==>
output = Popen(["mycmd", "myarg"], stdout=PIPE).communicate()[0]

··替换shell管道

output=`dmesg | grep hda`
==>
p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
output = p2.communicate()[0]

··替换os.system()

sts = os.system("mycmd" + " myarg")
==>
p = Popen("mycmd" + " myarg", shell=True)
sts = os.waitpid(p.pid, 0)

注意:

  • 通常不需要通过shell调用程序。
  • 查看returncode属性比退出状态更容易。

一个更实际的例子:

try:retcode = call("mycmd" + " myarg", shell=True)if retcode < 0:print >>sys.stderr, "Child was terminated by signal", -retcodeelse:print >>sys.stderr, "Child returned", retcode
except OSError, e:print >>sys.stderr, "Execution failed:", e

··替换os.spawn*

P_NOWAIT示例:

pid = os.spawnlp(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg")
==>
pid = Popen(["/bin/mycmd", "myarg"]).pid

P_WAIT示例:

retcode = os.spawnlp(os.P_WAIT, "/bin/mycmd", "mycmd", "myarg")
==>
retcode = call(["/bin/mycmd", "myarg"])

Vector示例:

os.spawnvp(os.P_NOWAIT, path, args)
==>
Popen([path] + args[1:])

Environment示例:

os.spawnlpe(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg", env)
==>
Popen(["/bin/mycmd", "myarg"], env={"PATH": "/usr/bin"})

··替换os.popen*

pipe = os.popen(cmd, mode='r', bufsize)
==>
pipe = Popen(cmd, shell=True, bufsize=bufsize, stdout=PIPE).stdoutpipe = os.popen(cmd, mode='w', bufsize)
==>
pipe = Popen(cmd, shell=True, bufsize=bufsize, stdin=PIPE).stdin(child_stdin, child_stdout) = os.popen2(cmd, mode, bufsize)
==>
p = Popen(cmd, shell=True, bufsize=bufsize,stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdin, child_stdout) = (p.stdin, p.stdout)(child_stdin,child_stdout,child_stderr) = os.popen3(cmd, mode, bufsize)
==>
p = Popen(cmd, shell=True, bufsize=bufsize,stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
(child_stdin,child_stdout,child_stderr) = (p.stdin, p.stdout, p.stderr)(child_stdin, child_stdout_and_stderr) = os.popen4(cmd, mode, bufsize)
==>
p = Popen(cmd, shell=True, bufsize=bufsize,stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
(child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout)

··替换popen2.*

注意:如果popen2函数的cmd参数是一个字符串,则该命令通过 /bin/sh 执行。如果是列表,则直接执行该命令。

(child_stdout, child_stdin) = popen2.popen2("somestring", bufsize, mode)
==>
p = Popen(["somestring"], shell=True, bufsize=bufsizestdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdout, child_stdin) = (p.stdout, p.stdin)(child_stdout, child_stdin) = popen2.popen2(["mycmd", "myarg"], bufsize, mode)
==>
p = Popen(["mycmd", "myarg"], bufsize=bufsize,stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdout, child_stdin) = (p.stdout, p.stdin)

popen2.Popen3 和 popen3.Popen4 基本上用作subprocess.Popen,除了:

  • subprocess.Popen如果执行失败则引发异常。
  • capturestderr参数被替换为stderr参数。
  • 必须指定stdin = PIPE和stdout = PIPE。
  • popen2默认关闭所有文件描述符,但必须使用subprocess.Popen指定close_fds = True。

参考:

python的subprocess.Popen()的简单用法

17.5. subprocess — Subprocess management

PEP 324 -- subprocess - New process module

python中使用subprocess.Popen中的返回值总结

Python_cmd的各种实现方法及优劣(subprocess.Popen, os.system和commands.getstatusoutput)

python-subprocess模块用法相关推荐

  1. Python re模块用法详解

    Python re模块用法详解 在 Python 爬虫过程中,实现网页元素解析的方法有很多,正则解析只是其中之一,常见的还有 BeautifulSoup 和 lxml,它们都支持网页 HTML 元素的 ...

  2. python subprocess使用_Python subprocess模块用法详解

    在 Python 2.7 及 Python 3 中,系统自带了 subprocess 模块,该模块主要用来管理子进程. 在使用该模块之前需要将其引入,方法如下: import subprocess 在 ...

  3. python subprocess模块 命令执行

    subprocess模块中定义了一个Popen类,通过它可以来创建进程,并与其进行复杂的交互.查看一下它的构造函数: __init__(self, args, bufsize=0, executabl ...

  4. Python subprocess模块

    subprocess subprocess模块介绍 subprocess模块是一个可以将系统内的命令结果赋值给变量并打印, 还可以输出命令执行状态,subprocess可以单独将 命令输出结果与执行状 ...

  5. python subprocess 模块

    subprocess 模块中有一个功能Popen , 可以在代码中调用系统的命令 其功能比os.system 更加强大 代码示例: command = 'python -u %s/generalMak ...

  6. python常用模块用法_python常用模块(一)

    #什么是模块呢?就是用一大坨代码来完成一个功能的代码集合,是不是简单易懂 #类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个 ...

  7. python常用模块用法_python笔记之常用模块用法分析

    python笔记之常用模块用法分析 内置模块(不用import就可以直接使用) 常用内置函数 help(obj) 在线帮助, obj可是任何类型 callable(obj) 查看一个obj是不是可以像 ...

  8. python shutil模块用法实例分析_Python shutil模块用法实例分析

    分享大神指教Python中的shutil模块的rmtree()方法如分享大神指教Python中的shutil模块的rmtree()方法如何实现.思路是怎样的rmtree() 是用来删除文件目录及其中的 ...

  9. Python学习:python数组模块用法

    array模块是python中实现的一种高效的数组存储类型.它和list相似,但是所有的数组成员必须是同一种类型,因此在创建数组的时候,就确定了数组的类型 计算机为数组分配一段连续的内存,从而支持对数 ...

  10. python ping模块用法_使用Python实现批量ping操作方法

    在日常的工作中,我们通常会有去探测目标主机是否存活的应用场景,单个的服务器主机可以通过计算机自带的DOS命令来执行,但是业务的存在往往不是单个存在的,通常都是需要去探测C段的主机(同一个网段下的存活主 ...

最新文章

  1. linux 进程内存分布及 堆分配和栈分配的特点
  2. c# dbgrid数据导出到xlsx和ini中实例
  3. 超实用!VLAN、TRUNK、VLAN间路由基础
  4. 系统安装重装与优化:chapter7 操作系统的修复与重装
  5. 【LOJ】#2184. 「SDOI2015」星际战争
  6. 政府公开数据可视化_公开演讲如何帮助您设计更好的数据可视化
  7. 前端学习(2525):实现过滤功能
  8. 【HTML5】HTML5支持的通用属性
  9. 程序设计与算法----递归之爬楼梯问题
  10. IT行业的职员加班到底有没有价值?
  11. Maven学习使用Nexus搭建Maven私服
  12. 为什么在idea没有preview_设计学研究的idea从哪里来?
  13. 算法笔记_面试题_1.爬楼梯
  14. 2022年最新二手苹果手机价格表
  15. 打开Word提示:Office已阻止访问以下嵌入对象,以便保护你的安全解决方法
  16. RT-Thread Smart上手指南~
  17. java毕业设计融呗智慧金融微资讯移动平台服务端源码+lw文档+mybatis+系统+mysql数据库+调试
  18. Yii2 中 checkboxlist 复选框 默认选中
  19. 国产计算机硬件发展史,计算机基础-计算机硬件发展史以及硬件
  20. 1023: 大小写转换 ZZULIOJ

热门文章

  1. 计算任意多边形的面积(Android)
  2. 个人网站模板颜色搭配技巧
  3. Android学习之Textview控件字体颜色设置及颜色色值
  4. 如何轻松应对述职专题二之PPT篇
  5. 2023年微软发布的第一个补丁都有什么?
  6. 给Android应用签名
  7. GPS几种基本定位模式原理概述及精度介绍
  8. 苹果ipa软件下载网站和软件的汇总
  9. 大一上学期期末计算机单选知识点,大一上学期计算机基础试题题库及答案
  10. vue实现全屏只显示内容不显示导航条和退出全屏调用事件