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天前
|
安全 Linux 网络安全
Kali 渗透测试:基于结构化异常处理的渗透-使用Python编写渗透模块(一)
Kali 渗透测试:基于结构化异常处理的渗透-使用Python编写渗透模块(一)
52 2
|
17天前
|
Python Windows 网络安全
Kali 渗透测试:基于结构化异常处理的渗透-使用Python编写渗透模块(二)
Kali 渗透测试:基于结构化异常处理的渗透-使用Python编写渗透模块(二)
43 2
|
17天前
|
Python
Datetime模块应用:Python计算上周周几对应的日期
Datetime模块应用:Python计算上周周几对应的日期
42 1
|
3天前
|
消息中间件 监控 网络协议
Python中的Socket魔法:如何利用socket模块构建强大的网络通信
本文介绍了Python的`socket`模块,讲解了其基本概念、语法和使用方法。通过简单的TCP服务器和客户端示例,展示了如何创建、绑定、监听、接受连接及发送/接收数据。进一步探讨了多用户聊天室的实现,并介绍了非阻塞IO和多路复用技术以提高并发处理能力。最后,讨论了`socket`模块在现代网络编程中的应用及其与其他通信方式的关系。
|
6天前
|
Python
Python 中常用的内置模块之`re`模块
【10月更文挑战第11天】 `re` 模块是 Python 内置的正则表达式处理工具,支持模式匹配、搜索、替换等功能。通过 `search`、`match`、`findall` 和 `sub` 等函数,结合正则表达式的元字符、分组、贪婪模式等特性,可高效完成文本处理任务。示例代码展示了基本用法,帮助快速上手。
9 1
|
6天前
|
JSON 数据格式 Python
Python基础-常用内置模块
【10月更文挑战第11天】 Python 内置模块丰富,涵盖系统交互、时间处理、数学运算、正则表达式、数据序列化等功能,如 `sys`、`os`、`time`、`datetime`、`random`、`math`、`re`、`json`、`pickle` 和 `csv` 等,极大提升了开发效率和代码质量。
8 1
|
10天前
|
Python
Python实用记录(四):os模块-去后缀或者改后缀/指定目录下图片或者子目录图片写入txt/csv
本文介绍了如何使用Python的os模块来操作文件,包括更改文件后缀、分割文件路径和后缀、将指定目录下的所有图片写入txt文档,以及将指定目录下所有子目录中的图片写入csv文档,并为每个子目录分配一个标签。
11 1
|
15天前
|
JSON Java Linux
python有用的模块
python有用的模块
|
17天前
|
安全 测试技术 数据库
Python编程--sys模块及OS模块简单用例
Python编程--sys模块及OS模块简单用例
12 1
|
17天前
|
JSON 数据格式 Python
Python编程:利用JSON模块编程验证用户
Python编程:利用JSON模块编程验证用户
17 1