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)
>>>
目录
相关文章
|
7天前
|
Python
在Python中,可以使用内置的`re`模块来处理正则表达式
在Python中,可以使用内置的`re`模块来处理正则表达式
19 5
|
17天前
|
Java 程序员 开发者
Python的gc模块
Python的gc模块
|
20天前
|
数据采集 Web App开发 JavaScript
python-selenium模块详解!!!
Selenium 是一个强大的自动化测试工具,支持 Python 调用浏览器进行网页抓取。本文介绍了 Selenium 的安装、基本使用、元素定位、高级操作等内容。主要内容包括:发送请求、加载网页、元素定位、处理 Cookie、无头浏览器设置、页面等待、窗口和 iframe 切换等。通过示例代码帮助读者快速掌握 Selenium 的核心功能。
62 5
|
24天前
|
Python
SciPy 教程 之 SciPy 模块列表 6
SciPy教程之常量模块介绍:涵盖公制、二进制(字节)、质量、角度、时间、长度、压强、体积、速度、温度、能量、功率及力学单位。示例展示了角度单位转换为弧度的几个常用常量。
19 7
|
24天前
|
Python
SciPy 教程 之 SciPy 模块列表 7
`scipy.constants` 模块提供了常用的时间单位转换为秒数的功能。例如,`constants.hour` 返回 3600.0 秒,表示一小时的秒数。其他常用时间单位包括分钟、天、周、年和儒略年。
17 6
|
21天前
|
Python
SciPy 教程 之 SciPy 模块列表 13
SciPy教程之SciPy模块列表13:单位类型。常量模块包含多种单位,如公制、二进制(字节)、质量、角度、时间、长度、压强、体积、速度、温度、能量、功率和力学单位。示例代码展示了如何使用`constants`模块获取零摄氏度对应的开尔文值(273.15)和华氏度与摄氏度的转换系数(0.5556)。
17 1
|
22天前
|
XML 前端开发 数据格式
超级详细的python中bs4模块详解
Beautiful Soup 是一个用于从网页中抓取数据的 Python 库,提供了简单易用的函数来处理导航、搜索和修改分析树。支持多种解析器,如 Python 标准库中的 HTML 解析器和更强大的 lxml 解析器。通过简单的代码即可实现复杂的数据抓取任务。本文介绍了 Beautiful Soup 的安装、基本使用、对象类型、文档树遍历和搜索方法,以及 CSS 选择器的使用。
53 1
|
23天前
|
Python
SciPy 教程 之 SciPy 模块列表 9
SciPy教程之常量模块介绍,涵盖多种单位类型,如公制、质量、角度、时间、长度、压强等。示例展示了如何使用`scipy.constants`模块查询不同压强单位对应的帕斯卡值,包括atm、bar、torr、mmHg和psi。
14 1
|
23天前
|
Python
SciPy 教程 之 SciPy 模块列表 8
SciPy教程之常量模块单位类型介绍。该模块包含多种单位,如公制、质量、角度、时间、长度、压强、体积、速度、温度、能量、功率和力学单位。示例展示了部分长度单位的转换值,例如英寸、英尺、海里等。
15 1
|
25天前
|
知识图谱 Python
SciPy 教程 之 SciPy 模块列表 5
本教程介绍SciPy常量模块中的单位类型,涵盖公制、质量、时间、长度等单位。示例代码展示了如何使用`scipy.constants`模块获取不同质量单位的千克值,如公吨、磅、盎司、原子质量单位等。
15 1