Python 3 uses subprocess to implement pipeline (pipe) Interactive Operation read/write communication, pythonsubprocess
Here we use shell in Windows for example:
From subprocess import * # because it is an example, all data is imported.
To facilitate your understanding, we use a simple piece of code to describe:
We can see that we use popenizer to create a sub-program named cmd.exe, And then we give his Stdin (standard input stream) Stdout (standard output stream );
Subprocess. PIPE is also used as the parameter, which is a special value to indicate that these channels must be open.(In Python3.5, the run () method is added for better operations)
Then proceed
Are you familiar with this information? This is the standard output of cmd!
Then the output is as follows:
The information we just written"Echo Hellwworlds \ r \ n"It seems that it has been written!
Note that we use p. stdin. flush () is used to refresh the input cache. The output information must also be "\ r \ n", at least in Windows. Otherwise, only refresh (p. stdin. flush) is invalid;
What have we done?
We successfully created the subroutine cmd.exe and wrote"Echo Hellwworlds \ r \ n"Then, cmd obtains and executes the command, and returns Hellwworlds. This is a simple read/write interaction!
More advanced use
Now that we can simply read and write data, add for and threading. It may taste better ~
1 # run. py 2 3 from subprocess import * 4 import threading 5 import time 6 7 p export popen('cmd.exe ', shell = True, stdin = PIPE, stdout = PIPE) 8 9 def run (): 10 global p11 while True: 12 line = p. stdout. readline () 13 if not line: # null, the 14 break15 print (">>>>>>", line. decode ("GBK") 16 17 print ("look up !!! EXIT = ") # Jump out of 18 19 20 w = threading. Thread (target = run) 21 22 p. stdin. write (" echo HELLW_WORLD! \ R \ n ". encode ("GBK") 23 p. stdin. flush () 24 time. sleep (1) # The delay is due to waiting for the thread to be ready for 25 p. stdin. write ("exit \ r \ n ". encode ("GBK") 26 p. stdin. flush () 27 28 w. start ()
Good. Guess what the output is?
There are a lot of line breaks because the result returned by cmd contains a line break, and a line break will be added to the print output, so two lines are changed. You can consider using sys. stdout. write to output, so there is no additional line feed.
In this case, you can create a basic read/write, so let's start encapsulation.
Encapsulated Pipe
If you really want to learn the code, read the code carefully.
110 rows
We have implemented all the processes in a class, and we can define three parameters, exit the feedback function, ready to feedback the function and output feedback function.
1 #-*-coding: UTF-8-*-2 3 import subprocess 4 import sys 5 import threading 6 7 class LoopException (Exception): 8 "loop Exception custom Exception, this exception does not mean that every cycle exits abnormally "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 Communication Pipeline class with any sub-process, interactive communication between pipelines 20 "21 def _ init _ (self, commande, func, exitfunc, readyfunc = None, 22 shell = True, s Tdin = subprocess. PIPE, stdout = subprocess. PIPE, stderr = subprocess. PIPE, code = "GBK "): 23 "24 commande command 25 func correct output feedback function 26 exitfunc exception feedback function 27 readyfunc call 28" 29 self when the pipeline is created. _ 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 "Private function" "38 try: 39 self. _ process = subprocess. popen (40 commande, 41 shell = shell, 42 stdin = stdin, 43 stdout = stdout, 44 stderr = stderr 45) 46 TB t 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 () # Ready 52 while True: 53 line = fun () 54 if not line: 55 break 56 try: 57 tmp = line. decode (self. _ code) 58 TB 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") # exit 66 67 68 def write (self, msg): 69 if self. _ flag: 70 # note the line feed 71 self. _ process. stdin. write (msg + self. _ CRFL ). encode (self. _ code) 72 self. _ process. stdin. flush () 73 # sys. stdin. write (msg) # What should I do? You cannot directly send commands using code. You can only use the default stdin 74 else: 75 raise LoopException ("Shell pipe error from '_ flag' not True! ") # Exit 76 77 78 def start (self): 79" start thread "" 80 self. _ thread. start () 81 82 def destroy (self): 83 "Stop and destroy itself" 84 process. stdout. close () 85 self. _ thread. stop () 86 del self 87 88 89 90 91 92 93 if _ name _ = '_ main __': # So let's start using it 94 e = None 95 96 # feedback function 97 def event (cls, line): # output feedback function 98 sys. stdout. write (line) 99 100 def exit (msg): # exit feedback function 101 print (msg) 102 103 def ready (): # thread ready feedback function 104 E. write ("dir") # Run 105 e. write ("ping www.baidu.com") 106 e. write ("echo Hello! Hello, China! Hello world! ") 107 e. write (" exit ") 108 109 e = SwPipe (" cmd.exe ", event, exit, ready) 110 e. start ()
Output:
As you can see, our commands are executed sequentially. Of course, there are still OS credits here.
So should your extensible Pipe class have been built?
A: The reason why I want to add the number of rows before this code is to prevent you fromCopy;Because you may never understand what happened here, but only understand how to use it.
By the way:
Please refer to the official documents for details. Subprocess. Popen. communicate may be more suitable for you to see what you are doing.
Refer:
Https://docs.python.org/3/library/subprocess.html
This is the end. If there is any error, please correct it.
Whether it is helpful or not, thank you for your patience.