Python 3 利用 subprocess 实现管道( pipe )交互操作读/写通信

来源:互联网 发布:物知身心 出有所长 编辑:程序博客网 时间:2024/06/09 03:20

http://www.cnblogs.com/suwings/p/6216279.html


#run.pyfrom subprocess import *import threadingimport timep =Popen('ping 127.0.0.1',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 士大夫十分!\r\n".encode("GBK"))p.stdin.flush()time.sleep(1) #延迟是因为等待一下线程就绪p.stdin.write("exit\r\n".encode("GBK"))p.stdin.flush()w.start()


封装Pipe


 不废话了,直接上代码,如果你真的想学会的话,还请认真自己读读代码。

 110行

我们实现了将所有的过程集中在一个类里面,并且可以定义三个参数,退出反馈函数,就绪反馈函数和输出反馈函数。

复制代码
  1 # -*- coding:utf-8 -*-  2   3 import subprocess    4 import sys  5 import threading  6   7 class LoopException(Exception):  8     """循环异常自定义异常,此异常并不代表循环每一次都是非正常退出的"""  9     def __init__(self,msg="LoopException"): 10         self._msg=msg 11  12     def __str__(self): 13         return self._msg 14  15  16  17 class SwPipe(): 18     """ 19     与任意子进程通信管道类,可以进行管道交互通信 20     """ 21     def __init__(self,commande,func,exitfunc,readyfunc=None, 22         shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE,code="GBK"): 23         """ 24         commande 命令 25         func 正确输出反馈函数 26         exitfunc 异常反馈函数 27         readyfunc 当管道创建完毕时调用 28         """ 29         self._thread = threading.Thread(target=self.__run,args=(commande,shell,stdin,stdout,stderr,readyfunc)) 30         self._code = code 31         self._func = func 32         self._exitfunc = exitfunc 33         self._flag = False 34         self._CRFL = "\r\n" 35  36     def __run(self,commande,shell,stdin,stdout,stderr,readyfunc): 37         """ 私有函数 """ 38         try: 39             self._process = subprocess.Popen( 40                 commande, 41                 shell=shell, 42                 stdin=stdin, 43                 stdout=stdout, 44                 stderr=stderr 45                 )   46         except OSError as e: 47             self._exitfunc(e) 48         fun = self._process.stdout.readline 49         self._flag = True 50         if readyfunc != None: 51             threading.Thread(target=readyfunc).start() #准备就绪 52         while True: 53             line = fun()   54             if not line:   55                 break 56             try: 57                 tmp = line.decode(self._code) 58             except UnicodeDecodeError: 59                 tmp =  \ 60                 self._CRFL + "[PIPE_CODE_ERROR] <Code ERROR: UnicodeDecodeError>\n"  61                 + "[PIPE_CODE_ERROR] Now code is: " + self._code + self._CRFL 62             self._func(self,tmp) 63  64         self._flag = False 65         self._exitfunc(LoopException("While Loop break"))   #正常退出 66  67  68     def write(self,msg): 69         if self._flag: 70             #请注意一下这里的换行 71             self._process.stdin.write((msg + self._CRFL).encode(self._code))  72             self._process.stdin.flush() 73             #sys.stdin.write(msg)#怎么说呢,无法直接用代码发送指令,只能默认的stdin 74         else: 75             raise LoopException("Shell pipe error from '_flag' not True!")  #还未准备好就退出 76  77  78     def start(self): 79         """ 开始线程 """ 80         self._thread.start() 81  82     def destroy(self): 83         """ 停止并销毁自身 """ 84         process.stdout.close() 85         self._thread.stop() 86         del self 87         88  89  90  91  92  93 if __name__ == '__main__':   #那么我们来开始使用它吧 94     e = None 95  96     #反馈函数 97     def event(cls,line):#输出反馈函数 98         sys.stdout.write(line) 99 100     def exit(msg):#退出反馈函数101         print(msg)102 103     def ready():#线程就绪反馈函数104         e.write("dir")  #执行105         e.write("ping www.baidu.com")106         e.write("echo Hello!World 你好中国!你好世界!")107         e.write("exit")108 109     e = SwPipe("cmd.exe",event,exit,ready)110     e.start()
复制代码

输出: