python-subprocess模块

简介:

一、subprocess 模块简介
subprocess模块用来生成子进程,并可以通过管道连接它们的输入/输出/错误,以及获得它们的返回值。
它用来代替多个旧模块和函数:
os.system
os.spawn*
os.popen*
popen2.*
commands.*

subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False)¶
subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False)¶
subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False)¶

  • subprocess.PIPE
    使用Popen时,用于 stdin, stdout和stderr参数的特殊值,表示打开连接标准流的管道。
  • subprocess.STDOUT
    使用Popen时,用于 stderr 参数的特殊值,表示将标准错误重定向到标准输出的同一个句柄。
  • 异常 subprocess.CalledProcessError
    当由 check_call()或 check_output()运行的进程返回非零状态值时抛出的异常。
  • returncode
    子进程的退出状态。
  • cmd
    子进程执行的命令。
  • output
    如果check_output()抛出异常时,子进程的输出值。

否则,没有这个值。

  1. 常用的参数
    为了支持各种用户使用情况 ,Popen构建函数接收多种可选参数。

对于最典型的情况,许多参数都保留有安全的默认值,这些最常用的方式如下

  1. args
    这个参数:单个字符,或者序列,传递多个字符串必须带shell=True,否则失败
  1. 48
    -rw-r--r-- 1 root root 5383 Nov 22 19:21 all.py
    -rw-r--r-- 1 root root 173 Nov 23 11:16 basics.py
    -rwxr-xr-x 1 root root 4164 Nov 21 13:59 get_linux_status.py
    -rw-r--r-- 1 root root 345 Nov 22 16:01 hostname.py
    -rw-r--r-- 1 root root 180 Nov 22 16:06 local_ip.py
    -rwxr-xr-x 1 root root 3198 Nov 22 14:58 mysql_status.py
    -rw-r--r-- 1 root root 10786 Nov 23 16:05 prog.py
    -rw-r--r-- 1 root root 269 Nov 23 16:43 supro.py
    0

    subprocess.call("ls -l")
    Traceback (most recent call last):

    File "", line 1, in
    File "/usr/lib/python2.7/subprocess.py", line 522, in call
    return Popen(popenargs, *kwargs).wait()
    File "/usr/lib/python2.7/subprocess.py", line 710, in init
    errread, errwrite)
    File "/usr/lib/python2.7/subprocess.py", line 1327, in _execute_child
    raise child_exception
    OSError: [Errno 2] No such file or directory

    1. shell

如果你使用Python来作为流程控制,那这样的设置会很有用,因为它提供了绝大多数的系统shell命令且可以很方便地使用
shell的各种功能,如 shell 管道,文件名通配符,环境变量扩展,以及用户目录扩展符 ~。
但是,需要注意的是,Python 提供了类似shell功能的实现。

  1. stdin, stdout 和 stderr
    stdin, stdout和stderr指定了执行程序的标准输入,标准输出和标准错误的文件句柄。

它们的值可以是PIPE, 一个存在的文件描述符(正整数),一个存在的文件对象,或 None.
PIPE 表示创建一个连接子进程的新管道。
默认值 为 None, 表示不做重定向。
子进程的文件句柄可以从父进程中继承得到。
另外,stderr可以设置值为 STDOUT,表示子进程的错误数据可以和标准输出是同一个文件句柄。
当stdout 或 stderr的值为管道 并且 universal_newlines的值为真时,
对于以 ‘U'模式参数打开的新行,所有行的结束都会转换成'n'。

  1. Popen构建函数
    subprocess中更底层的进程创建和管理可以通过Popen类实现。

它提供了更多的灵活性,程序员通过它能处理更多复杂的情况。
语法:

 class subprocess.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)

语义:

 在新进程中执行一个子程序。
 在Unix中,这个类使用 类似于 os.execvp()方式来执行子程序。
 在Windows中,这个类使用Windows的 CreateProcess()函数来执行子程序。

args: 一个程序参数序列,或者单个字符串。

  默认的,要执行的程序应该是序列的第一个字段。
  如果单个字符串,它的解析依赖于平台

在Unix中,如果 args是一个字符串,那么这个字符串解释成被执行程序的名字或路径。
然而,这种情况只能用在不需要参数的程序。

示例代码:

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

import subprocess
child = subprocess.Popen(["ping","-c","5","172.16.3.33"])
print("xxxxxxxxxxxxxxxxxxxx")

#从运行结果中可看出从运行结果中看到,父进程在开启子进程之后并没有等待child的完成,而是直接运行print。
import subprocess
child = subprocess.Popen(["ping","-c","10","www.baidu.com"])
print("xxxxxxxxxxxxxxxxxxxx")
xxxxxxxxxxxxxxxxxxxx
PING www.a.shifen.com (115.239.210.27): 56 data bytes
64 bytes from 115.239.210.27: icmp_seq=0 ttl=56 time=4.420 ms
64 bytes from 115.239.210.27: icmp_seq=1 ttl=56 time=4.005 ms
64 bytes from 115.239.210.27: icmp_seq=2 ttl=56 time=52.775 ms
64 bytes from 115.239.210.27: icmp_seq=3 ttl=56 time=3.841 ms
64 bytes from 115.239.210.27: icmp_seq=4 ttl=56 time=64.287 ms
Request timeout for icmp_seq 5
64 bytes from 115.239.210.27: icmp_seq=6 ttl=56 time=3.202 ms
64 bytes from 115.239.210.27: icmp_seq=7 ttl=56 time=3.924 ms
64 bytes from 115.239.210.27: icmp_seq=8 ttl=56 time=3.425 ms
64 bytes from 115.239.210.27: icmp_seq=9 ttl=56 time=3.054 ms
--- www.a.shifen.com ping statistics ---
10 packets transmitted, 9 packets received, 10.0% packet loss
round-trip min/avg/max/stddev = 3.054/15.881/64.287/22.961 ms
  1. 对比等待的情况:
  2. subprocess

child = subprocess.Popen(["ping","-c","5","www.baidu.com"])
child.wait()
print("xxxxxxxxxxxxxxxxxxxx")

运行结果:
import subprocess
child = subprocess.Popen(["ping","-c","5","www.baidu.com"])
child.wait()
print("xxxxxxxxxxxxxxxxxxxx")
PING www.a.shifen.com (115.239.210.27): 56 data bytes
64 bytes from 115.239.210.27: icmp_seq=0 ttl=56 time=5.616 ms
64 bytes from 115.239.210.27: icmp_seq=1 ttl=56 time=3.626 ms
64 bytes from 115.239.210.27: icmp_seq=2 ttl=56 time=4.511 ms
64 bytes from 115.239.210.27: icmp_seq=3 ttl=56 time=4.073 ms
64 bytes from 115.239.210.27: icmp_seq=4 ttl=56 time=142.602 ms
--- www.a.shifen.com ping statistics ---
5 packets transmitted, 5 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 3.626/32.086/142.602/55.262 ms
xxxxxxxxxxxxxxxxxxxx

此外,你还可以在父进程中对子进程进行其它操作,比如我们上面例子中的child对象:
child.poll() # 检查子进程状态
child.kill() # 终止子进程
child.send_signal() # 向子进程发送信号
child.terminate() # 终止子进程
子进程的PID存储在child.pid

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

>>> child1 = subprocess.Popen(["ls","-l"], stdout=subprocess.PIPE)
>>> print child1
<subprocess.Popen object at 0x7f112a1366d0>
>>>
>>> print (child1)
<subprocess.Popen object at 0x7f112a1366d0>
>>>
>>>
>>> out = child1.communicate()
>>> print out
('total 48\n-rw-r--r-- 1 root root  5383 Nov 22 19:21 all.py\n-rw-r--r-- 1 root root   173 Nov 23 11:16 basics.py\n-rwxr-xr-x 1 root root  4164 Nov 21 13:59 get_linux_status.py\n-rw-r--r-- 1 root root   345 Nov 22 16:01 hostname.py\n-rw-r--r-- 1 root root   180 Nov 22 16:06 local_ip.py\n-rwxr-xr-x 1 root root  3198 Nov 22 14:58 mysql_status.py\n-rw-r--r-- 1 root root 10786 Nov 23 16:05 prog.py\n-rw-r--r-- 1 root root   269 Nov 23 16:43 supro.py\n', None)
>>>
目录
相关文章
|
17天前
|
存储 开发者 Python
Python中的collections模块与UserDict:用户自定义字典详解
【4月更文挑战第2天】在Python中,`collections.UserDict`是用于创建自定义字典行为的基类,它提供了一个可扩展的接口。通过继承`UserDict`,可以轻松添加或修改字典功能,如在`__init__`和`__setitem__`等方法中插入自定义逻辑。使用`UserDict`有助于保持代码可读性和可维护性,而不是直接继承内置的`dict`。例如,可以创建一个`LoggingDict`类,在设置键值对时记录操作。这样,开发者可以根据具体需求定制字典行为,同时保持对字典内部管理的抽象。
|
19天前
|
存储 缓存 算法
Python中collections模块的deque双端队列:深入解析与应用
在Python的`collections`模块中,`deque`(双端队列)是一个线程安全、快速添加和删除元素的双端队列数据类型。它支持从队列的两端添加和弹出元素,提供了比列表更高的效率,特别是在处理大型数据集时。本文将详细解析`deque`的原理、使用方法以及它在各种场景中的应用。
|
4天前
|
Python
python学习14-模块与包
python学习14-模块与包
|
5天前
|
SQL 关系型数据库 数据库
Python中SQLite数据库操作详解:利用sqlite3模块
【4月更文挑战第13天】在Python编程中,SQLite数据库是一个轻量级的关系型数据库管理系统,它包含在一个单一的文件内,不需要一个单独的服务器进程或操作系统级别的配置。由于其简单易用和高效性,SQLite经常作为应用程序的本地数据库解决方案。Python的内置sqlite3模块提供了与SQLite数据库交互的接口,使得在Python中操作SQLite数据库变得非常容易。
|
10天前
|
索引 Python
「Python系列」Python operator模块、math模块
Python的`operator`模块提供了一系列内置的操作符函数,这些函数对应于Python语言中的内建操作符。使用`operator`模块可以使代码更加清晰和易读,同时也能提高性能,因为它通常比使用Python内建操作符更快。
27 0
|
15天前
|
数据采集 网络协议 API
python中其他网络相关的模块和库简介
【4月更文挑战第4天】Python网络编程有多个流行模块和库,如requests提供简洁的HTTP客户端API,支持多种HTTP方法和自动处理复杂功能;Scrapy是高效的网络爬虫框架,适用于数据挖掘和自动化测试;aiohttp基于asyncio的异步HTTP库,用于构建高性能Web应用;Twisted是事件驱动的网络引擎,支持多种协议和异步编程;Flask和Django分别是轻量级和全栈Web框架,方便构建不同规模的Web应用。这些工具使网络编程更简单和高效。
|
19天前
|
数据采集 数据挖掘 Python
Python中collections模块的Counter计数器:深入解析与应用
在Python的`collections`模块中,`Counter`是一个强大且实用的工具,它主要用于计数可哈希对象。无论是统计单词出现的频率,还是分析数据集中元素的分布情况,`Counter`都能提供快速且直观的结果。本文将深入解析`Counter`计数器的原理、用法以及它在实际应用中的价值。
|
20天前
|
Python
Python中的math和cmath模块:数学运算的得力助手
Python作为一种功能强大的编程语言,提供了丰富的数学运算功能。其中,math和cmath模块就是Python中用于数学运算的重要工具。math模块提供了基本的数学函数和常量,适用于实数运算;而cmath模块则提供了对复数运算的支持,使得Python在数学计算和工程应用中更加灵活和强大。
|
23天前
|
数据挖掘 Python
Python中的datetime模块:轻松拿捏时间操作
Python的`datetime`模块是处理日期和时间的核心工具,包括`date`、`time`、`datetime`、`timedelta`类。它可以创建、操作和格式化日期时间。
19 2
|
25天前
|
Python
Python random模块(获取随机数)常用方法和使用例子
`random`模块在Python中用于生成随机数。
21 0

热门文章

最新文章