这里我们用windows下的shell来举例:
subprocess *
为了方便你理解,我们用一个很简单的一段代码来说明:
我们成功的创建了子程序 cmd.exe,并且写入”echo hellwworlds\r\n” ,然后cmd获取了并且执行,于是返回 hellwworlds,这就是一次很简单的读写交互!
更高级的使用
既然我们已经可以简单的读写了,那么加点for和threading 吧,味道也许更佳喔~
#run.py
from subprocess import *
import threading
import time
p =popen(‘cmd.exe’,shell=true,stdin=pipe,stdout=pipe)
def run():
global p
while true:
line = p.stdout.readline()
if not line: #空则跳出
break
print(“>>>>>>”,line.decode(“gbk”))
print(“look up!!! exit ===”) #跳出
w =threading.thread(target=run)
p.stdin.write(“echo hellw_world!\r\n”.encode(“gbk”))
p.stdin.flush()
time.sleep(1) #延迟是因为等待一下线程就绪
p.stdin.write(“exit\r\n”.encode(“gbk”))
p.stdin.flush()
w.start()
很好很好,猜猜输出什么?
不废话了,直接上代码,如果你真的想学会的话,还请认真自己读读代码。
110行
我们实现了将所有的过程集中在一个类里面,并且可以定义三个参数,退出反馈函数,就绪反馈函数和输出反馈函数。
# -*- coding:utf-8 -*-
import subprocess
import sys
import threading
class loopexception(exception):
“””循环异常自定义异常,此异常并不代表循环每一次都是非正常退出的”””
def __init__(self,msg=”loopexception”):
self._msg=msg
def __str__(self):
return self._msg
class swpipe():
“””
与任意子进程通信管道类,可以进行管道交互通信
“””
def __init__(self,commande,func,exitfunc,readyfunc=none,
shell=true,stdin=subprocess.pipe,stdout=subprocess.pipe,stderr=subprocess.pipe,code=”gbk”):
“””
commande 命令
func 正确输出反馈函数
exitfunc 异常反馈函数
readyfunc 当管道创建完毕时调用
“””
self._thread = threading.thread(target=self.__run,args=(commande,shell,stdin,stdout,stderr,readyfunc))
self._code = code
self._func = func
self._exitfunc = exitfunc
self._flag = false
self._crfl = “\r\n”
def __run(self,commande,shell,stdin,stdout,stderr,readyfunc):
“”” 私有函数 “””
try:
self._process = subprocess.popen(
commande,
shell=shell,
stdin=stdin,
stdout=stdout,
stderr=stderr
)
except oserror as e:
self._exitfunc(e)
fun = self._process.stdout.readline
self._flag = true
if readyfunc != none:
threading.thread(target=readyfunc).start() #准备就绪
while true:
line = fun()
if not line:
break
try:
tmp = line.decode(self._code)
except unicodedecodeerror:
tmp = \
self._crfl + “[pipe_code_error] \n”
+ “[pipe_code_error] now code is: ” + self._code + self._crfl
self._func(self,tmp)
self._flag = false
self._exitfunc(loopexception(“while loop break”)) #正常退出
def write(self,msg):
if self._flag:
#请注意一下这里的换行
self._process.stdin.write((msg + self._crfl).encode(self._code))
self._process.stdin.flush()
#sys.stdin.write(msg)#怎么说呢,无法直接用代码发送指令,只能默认的stdin
else:
raise loopexception(“shell pipe error from ‘_flag’ not true!”) #还未准备好就退出
def start(self):
“”” 开始线程 “””
self._thread.start()
def destroy(self):
“”” 停止并销毁自身 “””
process.stdout.close()
self._thread.stop()
del self
if __name__ == ‘__main__’: #那么我们来开始使用它吧
e = none
#反馈函数
def event(cls,line):#输出反馈函数
sys.stdout.write(line)
def exit(msg):#退出反馈函数
print(msg)
def ready():#线程就绪反馈函数
e.write(“dir”) #执行
e.write(“ping www.baidu.com”)
e.write(“echo hello!world 你好中国!你好世界!”)
e.write(“exit”)
e = swpipe(“cmd.exe”,event,exit,ready)
e.start()
输出:
你可以看见,我们的指令都顺序的执行了。当然了这里面还有os的功劳。
那么你的可扩展的pipe类应该已经构建完毕了吧?
a: 我之所以要在这种代码前面加入行数的原因就是为了防止你复制;因为你可能永远不会明白这里究竟发生了什么,而是只懂得了使用。
顺便一提:
最好去参考一下官方的文档,已经讲得非常详细了。subprocess.popen.communicate 或许更适合你,看你是要进行什么事情。
以上就是详解python3利subprocess实现管道pipe交互操作读/写通信方法的详细内容,更多请关注 第一php社区 其它相关文章!