Python中使用subprocess库创建附加进程


Posted in Python onMay 11, 2021

前言

subprocess库提供了一个API创建子进程并与之通信。这对于运行生产或消费文本的程序尤其有好处,因为这个API支持通过新进行的标准输入和输出通道来回传数据。

本篇,将详细介绍Python创建附加进行的库:subprocess。

run(运行外部命令)

subprocess库本身可以替换os.system(),os.spawnv()等函数。现在我们来通过subprocess库运行一个外部命令,但不采用os.system()。示例如下:

import subprocess

completed = subprocess.run('whoami')
print(completed.returncode)

这里我们运行了一个windows系统常用的whoami命令,返回当前用户的名称,输出如下:

Python中使用subprocess库创建附加进程

这里,我们使用了subprocess.run调用了子进程运行windows命令。它返回一个CompletedProcess实例,它包含了与进行有关的信息。returncode为子进程的退出状态码。通常情况下,退出状态码为0则表示进程成功运行了;一个负值-N表示这个子进程被信号N终止了。

该函数还有许多参数,比如shell,默认值为False表示直接运行命令,如果主动赋值为True则会创建一个中间shell进程,由这个进程运行命令。

import subprocess

completed = subprocess.run('echo 123',shell=True)
print(completed.returncode)

比如这里,我们打印123。

该库还有一个call()函数,subprocess.run有一个check参数,如果没有设置该参数,等价于调用了call()函数。check默认值为False。

对于run()函数启动的进程,它的标准输入输出通道会绑定到父进程的输入输出。这说明调用程序无法捕获命令的输出。不过,我们可以通过为stdout和stderr参数传入PIPE来捕获输出,以备以后处理。

import subprocess

completed = subprocess.run('whoami',stdout=subprocess.PIPE)
print(completed.returncode)
print(len(completed.stdout))
print(completed.stdout.decode('UTF-8'))

运行之后,效果如下:

Python中使用subprocess库创建附加进程

如果设置run()函数的参数check=True与stdout为PIPE,等价于调用了check_output()函数。

通过Shell返回消息

本例会通过一个子shell运行命令,在命令返回错误码并退出之前,将详细输入到控制台。实例如下:

import subprocess

try:
    completed = subprocess.run(
        'echoa 123',
        shell=True,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE, )
except subprocess.CalledProcessError as err:
    print("ERROR:", err)
else:
    print("else")
    print(completed.returncode)
    print(len(completed.stdout))
    print(completed.stdout.decode('UTF-8'))
    print(len(completed.stderr))
    print(completed.stderr.decode('gbk'))

运行之后,效果如下:

Python中使用subprocess库创建附加进程

这里我们输入了一个错误的命令,可以看到因为命令错误,并没有输出命令的执行结果,0和64中间就是completed.stdout,为空。而命令将错误消息返回了。这是因为我们设置了stdout与stderr为subprocess.PIPE,表明这些通道要开放。这样我们才能获取子shell运行的结果获取所运行的错误提示。(读者可以将命令改正确后可以发现错误消息没有了,正确执行结果会输出。这就是subprocess库创建进程的通信机制)

需要注意的是,如果需要抑制输出效果,可以将stdout与stderr设置为subprocess.DEVNULL。不过改了之后,上面代码肯定会报错,因为管道关闭,通信也就关闭了。也就是没有这些参数了。

直接处理管道

subprocess库还有一个非常重要的类Popen,它是用来建立其他API的底层API,对更复杂的进程交互很有用。

比如run(),call(),check_call()和check_output()函数都是Popen类的包装器。直接使用Popen可以更好的控制如何运行命令以及如何处理输入和输出流。Popen的构造函数利用参数建立新进程,使父进程可以通过管道与之通信。

下面,我们来分别介绍进程间通信的方式。

与进程的单项通信

要运行一个进程并读取它的所有输出,可以设置stdout为PIPE并调用communicate()函数。示例如下:

import subprocess

prc = subprocess.Popen('whoami', stdout=subprocess.PIPE)
stdout_value = prc.communicate()[0].decode('utf-8')
print(repr(stdout_value))

如上面代码所示,Popen会在内部管理数据读取。运行之后,效果如下:

Python中使用subprocess库创建附加进程

如果你需要调用一个管道,并完成写数据的操作,可以设置stdin为PIPE。

import subprocess

prc = subprocess.Popen(["cmd", "/c", 'type', '-'], stdin=subprocess.PIPE)
prc.communicate('stdin'.encode('UTF-8'))

与进程的双向通信

要完成进程的双向通信,可以直接将stdin与stdout都设置为PIPE即可。示例如下:

import subprocess

cmd = "cmd /c type E:/Project/debug.log"
cmd.encode('utf-8')
prc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
msg = 'stdin'.encode('UTF-8')
stdout_value = prc.communicate(msg)[0].decode('utf-8')
print(repr(stdout_value))

至于如果命令行错误需要捕获错误消息,可以直接将stderr也设置为PIPE。

连接管道段

在Linux系统中,我们可以将多个命令连接成一个管线,即可以把它们的输入输出串联在一起。通过Popen我们也可以完成类似的操作,只需要将一个Popen实例的stdout属性被用左管线中下一个Popen实例的stdin参数即可。至于最后肯定还是要设置为PIPE,毕竟我们还是要获取多个管道段消息结果,示例如下:

import subprocess

cmd1 = "cmd /c type E:/Project/debug.log"
proc1 = subprocess.Popen(cmd1, stdout=subprocess.PIPE, encoding='utf-8')

cmd2 = "tree /F | findstr 拒绝访问"
proc2 = subprocess.Popen(cmd1, stdout=subprocess.PIPE, stdin=proc1.stdout, encoding='utf-8')

result = proc2.stdout

for line in result:
    print(line.decode('utf-8').strip())

sys的命令交互

在我们学习Python时,一般使用input()进行用户输入数据。但是其实sys库也可以进行输入输出判断,但它涉及的是进程间的交互,示例如下:

import sys

sys.stderr.write('开始\n')
sys.stderr.flush()

while True:
    next_line = sys.stdin.readline()
    sys.stderr.flush()
    if next_line.strip() == "9599":
        break
    sys.stdout.write(next_line)
    sys.stdout.flush()
sys.stderr.write('结束\n')
sys.stderr.flush()

运行之后,效果如下:

Python中使用subprocess库创建附加进程

到此这篇关于Python中使用subprocess库创建附加进程的文章就介绍到这了,更多相关Python附加进程内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
教你如何将 Sublime 3 打造成 Python/Django IDE开发利器
Jul 04 Python
python使用MySQLdb访问mysql数据库的方法
Aug 03 Python
python爬虫_实现校园网自动重连脚本的教程
Apr 22 Python
Python实现将Excel转换成为image的方法
Oct 23 Python
python实现朴素贝叶斯算法
Nov 19 Python
padas 生成excel 增加sheet表的实例
Dec 11 Python
python使用sessions模拟登录淘宝的方式
Aug 16 Python
详解mac python+selenium+Chrome 简单案例
Nov 08 Python
Python单元测试与测试用例简析
Nov 09 Python
python 解决cv2绘制中文乱码问题
Dec 23 Python
将python字符串转化成长表达式的函数eval实例
May 11 Python
python 爬取百度文库并下载(免费文章限定)
Dec 04 Python
有趣的二维码:使用MyQR和qrcode来制作二维码
python保存大型 .mat 数据文件报错超出 IO 限制的操作
May 10 #Python
Python批量将csv文件转化成xml文件的实例
python基础之爬虫入门
python设置 matplotlib 正确显示中文的四种方式
提取视频中的音频 Python只需要三行代码!
Python-typing: 类型标注与支持 Any类型详解
May 10 #Python
You might like
实现分十页分向前十页向后十页的处理
2006/10/09 PHP
DOM XPATH获取img src值的query
2013/09/23 PHP
PHP使用正则表达式实现过滤非法字符串功能示例
2018/06/04 PHP
PHP面向对象程序设计之构造方法和析构方法详解
2019/06/13 PHP
PHP接入微信H5支付的方法示例
2019/10/28 PHP
PHP获取php,mysql,apche的版本信息及更多服务器信息
2021/03/09 PHP
jQuery参数列表集合
2011/04/06 Javascript
js实现同一页面多个不同运动效果的方法
2015/04/10 Javascript
JavaScript中的toDateString()方法使用详解
2015/06/12 Javascript
javaScript中的原型解析【推荐】
2016/05/05 Javascript
JQuery validate插件Remote用法大全
2016/05/15 Javascript
Bootstrap自定义文件上传下载样式
2016/05/26 Javascript
详解Javascript 中的 class、构造函数、工厂函数
2017/12/20 Javascript
vue-scroller记录滚动位置的示例代码
2018/01/17 Javascript
vue translate peoject实现在线翻译功能【新手必看】
2018/06/07 Javascript
PWA介绍及快速上手搭建一个PWA应用的方法
2019/01/27 Javascript
JS代码屏蔽F12,右键,粘贴,复制,剪切,选中,操作实例
2019/09/17 Javascript
JS实现点击下拉列表文本框中出现对应的网址,点击跳转按钮实现跳转
2019/11/25 Javascript
vue 在服务器端直接修改请求的接口地址
2020/12/19 Vue.js
在IIS服务器上以CGI方式运行Python脚本的教程
2015/04/25 Python
Python中datetime模块参考手册
2017/01/13 Python
Python实现列表删除重复元素的三种常用方法分析
2017/11/24 Python
python机器学习实战之K均值聚类
2017/12/20 Python
学生信息管理系统python版
2018/10/17 Python
python实现指定字符串补全空格、前面填充0的方法
2018/11/16 Python
Python、 Pycharm、Django安装详细教程(图文)
2019/04/12 Python
Django框架会话技术实例分析【Cookie与Session】
2019/05/24 Python
keras 使用Lambda 快速新建层 添加多个参数操作
2020/06/10 Python
JOSEPH官网:英国奢侈时尚品牌
2018/01/31 全球购物
优秀医生事迹材料
2014/02/12 职场文书
幼儿园春季开学寄语
2014/04/03 职场文书
校园绿化美化方案
2014/06/08 职场文书
优秀员工推荐材料
2014/12/20 职场文书
2015年城管个人工作总结范文
2015/04/20 职场文书
幼儿园综治宣传月活动总结
2015/05/07 职场文书
傲慢与偏见电影观后感
2015/06/10 职场文书