Python--subprocess系统命令模块-深入

 

当我们运行python的时候,我们都是在创建并运行一个进程。正如我们在Linux进程基础中介绍的那样,一个进程可以fork一个子进程,并让这个子进程exec另外一个程序。在Python中,我们通过标准库中的subprocess包来fork一个子进程,并运行一个外部的程序(fork,exec见Linux进程基础)。

 

 

 

subprocess包中定义有数个创建子进程的函数,这些函数分别以不同的方式创建子进程,所以我们可以根据需要来从中选取一个使用。另外subprocess还提供了一些管理标准流(standard stream)和管道(pipe)的工具,从而在进程间使用文本通信。

 

 

 

使用subprocess包中的函数创建子进程的时候,要注意:

 

1) 在创建子进程之后,父进程是否暂停,并等待子进程运行。

 

2) 函数返回什么

 

3) 当returncode不为0时,父进程如何处理。

 

 

 

subprocess.call()
父进程等待子进程完成
返回退出信息(returncode,相当于exit code,见Linux进程基础)

 

 

 

subprocess.check_call()

 

父进程等待子进程完成

 

返回0

 

检查退出信息,如果returncode不为0,则举出错误subprocess.CalledProcessError,该对象包含有returncode属性,可用try...except...来检查(见Python错误处理)。

 

 

 

subprocess.check_output()

 

父进程等待子进程完成

 

返回子进程向标准输出的输出结果

 

检查退出信息,如果returncode不为0,则举出错误subprocess.CalledProcessError,该对象包含有returncode属性和output属性,output属性为标准输出的输出结果,可用try...except...来检查。

 

subprocess的目的就是启动一个新的进程并且与之通信

 

python执行系命令的相关的模块和函数的功能均在 subprocess 模块中实现,并提供了丰富的功能用

import subprocess

res=subprocess.Popen('dir',shell=True,stdout=subprocess.PIPE)
print(res)
print(res.stdout.read().decode('gbk'))



<subprocess.Popen object at 0x00425CF0>
 驱动器 F 中的卷是 娱乐
 卷的序列号是 000A-189E

 F:\python\课堂笔记\day06\subprocess模块 的目录

2017/06/07  16:38    <DIR>          .
2017/06/07  16:38    <DIR>          ..
2017/06/07  16:38             1,159 test.py
               1 个文件          1,159 字节
               2 个目录 82,441,273,344 可用字节

 stdin, stdout, stderr分别表示程序的标准输入、输出、错误句柄。他们可以是PIPE,文件描述符或文件对象,也可以设置为None,表示从父进程继承。

shell设为true,程序将通过shell来执行。

import subprocess

res=subprocess.Popen('ping',shell=True,
                     stderr=subprocess.PIPE,
                     stdout=subprocess.PIPE)

print('=====>',res.stdout.read().decode("gbk"))

用法: ping [-t] [-a] [-n count] [-l size] [-f] [-i TTL] [-v TOS]
           [-r count] [-s count] [[-j host-list] | [-k host-list]]
           [-w timeout] [-R] [-S srcaddr] [-4] [-6] target_name

选项:
    -t             Ping 指定的主机,直到停止。
                   若要查看统计信息并继续操作 - 请键入 Control-Break;
                   若要停止 - 请键入 Control-C。
    -a             将地址解析成主机名。
    -n count       要发送的回显请求数。
    -l size        发送缓冲区大小。
    -f             在数据包中设置“不分段”标志(仅适用于 IPv4)。
    -i TTL         生存时间。
    -v TOS         服务类型(仅适用于 IPv4。该设置已不赞成使用,且
                   对 IP 标头中的服务字段类型没有任何影响)。
    -r count       记录计数跃点的路由(仅适用于 IPv4)。
    -s count       计数跃点的时间戳(仅适用于 IPv4)。
    -j host-list   与主机列表一起的松散源路由(仅适用于 IPv4)。
    -k host-list   与主机列表一起的严格源路由(仅适用于 IPv4)。
    -w timeout     等待每次回复的超时时间(毫秒)。
    -R             同样使用路由标头测试反向路由(仅适用于 IPv6)。
    -S srcaddr     要使用的源地址。
    -4             强制使用 IPv4。
    -6             强制使用 IPv6。
win ping打印
#ls |grep txt$
res1=subprocess.Popen(r'dir F:\python\课堂笔记\day06',shell=True,stdout=subprocess.PIPE)
# print(res1.stdout.read())

res=subprocess.Popen(r'findstr json*',shell=True,
                     stdin=res1.stdout,
                     stderr=subprocess.PIPE,
                     stdout=subprocess.PIPE)

print('===>',res.stdout.read().decode('gbk'))#管道取一次就空了
print('===>',res.stdout.read().decode('gbk'))

===> 2017/06/07  15:22                48 a.json
2017/06/07  15:22                48 b.json

===> 
#ls |grep txt$

 

posted @ 2017-06-07 17:36  真-小亮亮  阅读(322)  评论(0编辑  收藏  举报
#20191216