subprocess– Creating additional processes
The Subprocess module provides a consistent way to create and process additional processes, providing a more advanced interface than other modules in the standard library. Used to replace the following modules:
Os.system (), OS.SPAWNV (), the Popen () function in the OS and Popen2 modules, and commands ().
1. Run external commands
Subprocess.call (Command) method
The call method of subprocess can be used to execute an external command, but the method cannot return the result of execution, only return the execution status code: Success (0) or error (not 0)
The command in the call () method can be a list or a string that needs to be executed with the native shell as a string:
Importsubprocess#Execute DF-HL Command#Method 1:>>> Subprocess.call (['ls','- L']) Total8DRWXRWXR-x 4 ws ws 4096 Nov 25 13:50MONITORSYSTEMDRWXRWXR-X 2 ws ws 4096 Feb 19 10:09tmp0#Method 2:>>> Subprocess.call ("ls-l", shell=True) Total8DRWXRWXR-x 4 ws ws 4096 Nov 25 13:50MONITORSYSTEMDRWXRWXR-X 2 ws ws 4096 FEB 10:09 tmp
As shown in the example above, although we can see the result of the execution, the actual obtained value is just the status code
>>> output = Subprocess.call ("ls-l", shell=8drwxrwxr-x 4 ws WS 4096 Nov 13:50 monitorsystemdrwxrwxr-x 2 ws ws 4096 FEB 10:09 tmpprint(output) 0
2. Error handling
Subprocess.check_call () method
We said that call execution returns a status code, and we can use the Check_call () function to detect the execution of the command, and if unsuccessful, it will return subprocess. Calledprocesserror exception
Try : subprocess.check_call ("ls-t", shell=True) except subprocess. Calledprocesserror as err: print("Command Error" not Foundcommand Error
3. Capturing output results
Subprocess.check_output () method
The
Call () method starts a process whose standard input output is bound to the input and output of the parent process. The calling program could not get the output of the command. However, the output can be captured by the Check_output () method.
# The following tests run results for python3.4 >>> output=subprocess.check_output ("ls-l", Shell =True)>>> outputb'total8\ndrwxrwxr-x 4 ws ws 4096 Nov 13:50 monitorsystem\ Ndrwxrwxr-x 2 ws ws 4096 Feb 10:09 tmp\n'print(Output.decode ('utf-8' c13> '8drwxrwxr-x 4 ws ws 4096 Nov 13:50 monitorsystemdrwxrwxr-x 2 ws ws 4096 FEB 10:09 tmp
The following example performs an error capture when the Chek_output () method executes a command exception and avoids output to the console.
Try : = Subprocess.check_output ("lt-l", Shell=true, stderr=subprocess. STDOUT)except subprocess. Calledprocesserror as err: print("Command Error", Err) # execution result 'lt-l' returned Non-zero exit status 127
Direct processing of pipelines
Subprocess. Popen () method
function call (), Check_call (), and Check_output () are all wrappers for the Popen class. Using Popen directly has more control over how commands are run and how to handle their input and output. If you pass different parameters for stdin, stdout, and stderr.
- One-way communication with processes
After invoking the command with the Popen () method, you can set the STDOUT value to pipe, and then call communicate () to get the result
Returns the result as a tuple. In Python3 the result is a byte type, to get the STR type requires decode conversion
Output results (Read)
#direct execution of command output to screen>>> subprocess. Popen ("ls-l", shell=True)<subprocess. Popen object at 0x7febd4175198>>>> Total 12DRWXRWXR-x 4 ws ws 4096 Nov 25 13:50Monitorsystem-rw-rw-r--1 ws ws 8 FEB 25 10:38TESTDRWXRWXR-X 2 ws ws 4096 Feb 19 10:09tmp#do not output to the screen, output to a variable>>> proc = subprocess. Popen (['Echo','"Stdout"'],stdout=subprocess. PIPE)#communicate return standard output or standard error message>>> Stdout_value =proc.communicate ()>>>Stdout_value (b'"Stdout" \ n', None)>>> proc = subprocess. Popen (['ls','- L'],stdout=subprocess. PIPE)>>> Stdout_value =proc.communicate ()>>>Stdout_value (b'Total 8\ndrwxrwxr-x 4 ws ws 4096 Nov 13:50 monitorsystem\ndrwxrwxr-x 2 ws ws 4096 Feb 10:09 tmp\n', None)>>>>>>Print(Stdout_value[0]). Decode ('Utf-8') ) Total8DRWXRWXR-x 4 ws ws 4096 Nov 25 13:50MONITORSYSTEMDRWXRWXR-X 2 ws ws 4096 Feb 19 10:09tmp#output the results to a file>>> file_handle = open ("/home/ws/t.log",'w+')>>> subprocess. Popen ("ls-l", shell=true,stdout=file_handle) t.log:drwxrwxr-x 4 ws ws 4096 Nov 25 13:50Monitorsystem-rw-rw-r--1 ws ws 8 FEB 25 10:38Test-rw-rw-r--1 ws ws 0 FEB 25 11:24T.LOGDRWXRWXR-X 2 ws ws 4096 FEB 10:09 tmp
2 Two-way communication with process
>>> proc = subprocess. Popen ('Cat', Shell=true, stdin=subprocess. PIPE, stdout=subprocess. PIPE)>>> msg ='Hello World'. Encode ('Utf-8')#write to input pipeline>>>proc.stdin.write (msg)11>>> Stdout_value =proc.communicate ()>>>Stdout_value (b'Hello World', None)#The Shtin can also be used for input and output processes that require mutual interaction#The following implementation opens the Python3 terminal and executes a print command>>>proc = subprocess. Popen (['Python3'],stdin=subprocess. Pipe,stdout=subprocess. PIPE, stderr=subprocess. PIPE,)>>>proc.stdin.write ('print ("HelloWorld")'. Encode ('Utf-8'))>>>out_value,err_value=proc.communicate ()>>>Print(Out_value)>>>Print(out_value) b'helloworld\n'>>>Print(err_value) b"'
The Popen.communicate () method is used to interact with child processes: Send data to stdin, and read data from stdout and stderr until EOF is received. Wait for the child process to end.
Capturing error output
>>> proc = subprocess. Popen (['Python3'],stdin=subprocess. Pipe,stdout=subprocess. PIPE, stderr=subprocess. PIPE,)>>> Proc.stdin.write ('print "HelloWorld"'. Encode ('Utf-8'))18>>> out_value,err_value=proc.communicate ()>>>Out_valueb"'>>>Print(Err_value.decode ('Utf-8')) File"<stdin>", Line 1Print "HelloWorld"^syntaxerror:missing parenthesesinchCall to'Print'
Popen Other methods
- Popen.pid viewing the child process ID
Popen.returncode Gets the child process status code, 0 indicates the end of the child process, none is not finished
When invoking system commands using Popen, it is recommended to use communicate to interact with stdin and get the output (stdout), which ensures that the child process exits gracefully to avoid the zombie process. Look at the following example
>>> proc = subprocess. Popen ('ls-l', Shell=true, stdout=subprocess. PIPE)#current child process ID>>>Proc.pid28906#return status is None, process not ended>>>Print(proc.returncode) None#after submission via communicate>>> Out_value =proc.communicate ()>>>Proc.pid28906#returns a status of 0, the child process automatically ends>>>Print(proc.returncode) 0
Python module-subprocess