python-subprocess模块用法
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=None, timeout=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_EVENT 和 CTRL_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模块用法相关推荐
- Python re模块用法详解
Python re模块用法详解 在 Python 爬虫过程中,实现网页元素解析的方法有很多,正则解析只是其中之一,常见的还有 BeautifulSoup 和 lxml,它们都支持网页 HTML 元素的 ...
- python subprocess使用_Python subprocess模块用法详解
在 Python 2.7 及 Python 3 中,系统自带了 subprocess 模块,该模块主要用来管理子进程. 在使用该模块之前需要将其引入,方法如下: import subprocess 在 ...
- python subprocess模块 命令执行
subprocess模块中定义了一个Popen类,通过它可以来创建进程,并与其进行复杂的交互.查看一下它的构造函数: __init__(self, args, bufsize=0, executabl ...
- Python subprocess模块
subprocess subprocess模块介绍 subprocess模块是一个可以将系统内的命令结果赋值给变量并打印, 还可以输出命令执行状态,subprocess可以单独将 命令输出结果与执行状 ...
- python subprocess 模块
subprocess 模块中有一个功能Popen , 可以在代码中调用系统的命令 其功能比os.system 更加强大 代码示例: command = 'python -u %s/generalMak ...
- python常用模块用法_python常用模块(一)
#什么是模块呢?就是用一大坨代码来完成一个功能的代码集合,是不是简单易懂 #类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个 ...
- python常用模块用法_python笔记之常用模块用法分析
python笔记之常用模块用法分析 内置模块(不用import就可以直接使用) 常用内置函数 help(obj) 在线帮助, obj可是任何类型 callable(obj) 查看一个obj是不是可以像 ...
- python shutil模块用法实例分析_Python shutil模块用法实例分析
分享大神指教Python中的shutil模块的rmtree()方法如分享大神指教Python中的shutil模块的rmtree()方法如何实现.思路是怎样的rmtree() 是用来删除文件目录及其中的 ...
- Python学习:python数组模块用法
array模块是python中实现的一种高效的数组存储类型.它和list相似,但是所有的数组成员必须是同一种类型,因此在创建数组的时候,就确定了数组的类型 计算机为数组分配一段连续的内存,从而支持对数 ...
- python ping模块用法_使用Python实现批量ping操作方法
在日常的工作中,我们通常会有去探测目标主机是否存活的应用场景,单个的服务器主机可以通过计算机自带的DOS命令来执行,但是业务的存在往往不是单个存在的,通常都是需要去探测C段的主机(同一个网段下的存活主 ...
最新文章
- linux 进程内存分布及 堆分配和栈分配的特点
- c# dbgrid数据导出到xlsx和ini中实例
- 超实用!VLAN、TRUNK、VLAN间路由基础
- 系统安装重装与优化:chapter7 操作系统的修复与重装
- 【LOJ】#2184. 「SDOI2015」星际战争
- 政府公开数据可视化_公开演讲如何帮助您设计更好的数据可视化
- 前端学习(2525):实现过滤功能
- 【HTML5】HTML5支持的通用属性
- 程序设计与算法----递归之爬楼梯问题
- IT行业的职员加班到底有没有价值?
- Maven学习使用Nexus搭建Maven私服
- 为什么在idea没有preview_设计学研究的idea从哪里来?
- 算法笔记_面试题_1.爬楼梯
- 2022年最新二手苹果手机价格表
- 打开Word提示:Office已阻止访问以下嵌入对象,以便保护你的安全解决方法
- RT-Thread Smart上手指南~
- java毕业设计融呗智慧金融微资讯移动平台服务端源码+lw文档+mybatis+系统+mysql数据库+调试
- Yii2 中 checkboxlist 复选框 默认选中
- 国产计算机硬件发展史,计算机基础-计算机硬件发展史以及硬件
- 1023: 大小写转换 ZZULIOJ