Subprocess is used to replace some old modules and functions, such as Os.system, os.spawn*, os.popen*, popen2.*, and commands.*.
The purpose of subprocess is to start a new process and communicate with it.
1.Popen
Only one class is defined in the Subprocess module: Popen. You can use Popen to create processes and make complex interactions with processes. Its constructor is as follows:
Subprocess. Popen (args, bufsize=0, Executable=none, Stdin=none, Stdout=none, Stderr=none, Preexec_fn=none, Close_fds=false, shell= False, Cwd=none, Env=none, Universal_newlines=false, Startupinfo=none, creationflags=0)
The parameters are interpreted as follows:
Parameters |
Description |
Args |
String or List |
BufSize |
0 No buffering 1 row buffer Other positive buffer sizes Negative values with default system buffering (generally full buffering) |
Executable |
Not normally, args. The first item in a string or list represents the program name |
Stdin StdOut StdErr |
None does not have any redirects, inherits the parent process Pipe Creation Pipeline File Object File descriptor (integer) StdErr can also be set to STDOUT |
Preexec_fn |
hook function, executed between fork and exec. (Unix) |
Close_fds |
Whether to close files other than 0/1/2 before executing a new process under Unix File descriptors under Windows that do not inherit or inherit from the parent process |
Shell |
For real. UNIX is equivalent to args preceded by the addition of "/bin/sh" "-C" window, the equivalent of adding "cmd.exe/c" |
Cwd |
Set up working directory |
Env |
Setting environment variables |
Universal_newlines |
Various line breaks are processed uniformly into ' \ n ' |
Startupinfo |
Structure passed to CreateProcess under window |
Creationflags |
Under Windows, pass Create_new_console Create your own console window |
(1) Simple control of sub-processes
Example 1
#!/usr/bin/python3import subprocesspingp = subprocess. Popen (args='ping-n 4 www.baidu.com', shell=True) print (pingp.pid)print ( Pingp.returncode)
The execution results are as follows:
D:\workspace\python\python3\practise\subprocess>Python3 demo01.py2356noned:\workspace\python\python3\practise\subprocess>Pinging www.a.shifen.com [115.239.210.27] with 32bytes of data:reply from115.239.210.27:bytes=32 time=9ms ttl=57Reply from115.239.210.27:bytes=32 time=11ms ttl=57Reply from115.239.210.27:bytes=32 time=26ms ttl=57Reply from115.239.210.27:bytes=32 time=7ms ttl=57Ping Statistics for115.239.210.27: Packets:sent= 4, Received = 4, Lost = 0 (0%loss), approximate round trip timesinchmilli-Seconds:minimum= 7ms, Maximum = 26ms, Average = 13ms
As you can see from the output, the code produces a child process and executes the command specified in args, and executes the following statement. Because of the latency of the network application, this makes the output of the external command output after printing out the process ID and return value.
Because external programs are executed in a newly generated subroutine, it is possible to confuse the output of the original process and the child process back if it is not restricted. If you need to wait for the child process to end, you can use the wait () function in the Popen class, as shown in the following code:
Example 2
#!/usr/bin/python3import= subprocess. Popen (args='ping-n 4 www.baidu.com', shell=True)pingp.wait () #等待进程完成 Print(pingp.pid)print(pingp.returncode)
The execution results are as follows:
D:\workspace\python\python3\practise\subprocess>python3 demo01.pypinging www.a.shifen.com [115.239.210.27] with 32bytes of data:reply from115.239.210.27:bytes=32 time=14ms ttl=57Reply from115.239.210.27:bytes=32 time=7ms ttl=57Reply from115.239.210.27:bytes=32 time=6ms ttl=57Reply from115.239.210.27:bytes=32 time=17ms ttl=57Ping Statistics for115.239.210.27: Packets:sent= 4, Received = 4, Lost = 0 (0%loss), approximate round trip timesinchmilli-Seconds:minimum= 6ms, Maximum = 17ms, Average =11ms185080
The wait () function waits for the child process to complete and returns the child process's return value.
As you can see from the output above, the process ID and the return value of the child process are now behind the child process output. At the same time, the return value of the child process has changed to 0, indicating that the child process has exited successfully.
In addition, you can also perform other operations on the child process in the parent process, such as in our example:
PINGP # Check child process status PINGP # terminating a child process PINGP # send a signal to a child process PINGP # Terminate child Process PS: The PID of the subprocess is stored in child.pid
(2) sub-process text flow control
In the two example programs above, when a child process is created, its standard input, standard output, and standard error handling are not related to the original process. If you want to manage the input and output of a child process, you can change class parameters such as stdin, stdout, and stderr in the Popen class. How to use the previous process creation method, you need to redirect the input output.
Example 3
#!/usr/bin/python3import= subprocess. Popen (args='ping-n 4 www.baidu.com', shell=true,stdout = subprocess. PIPE) pingp.wait ()print(PingP.stdout.read ()) #读取进程的输出信息,print( pingp.pid)print(pingp.returncode)
Code Description:
- In the Popen class parameter, stdin, stdout, and stderr are used to specify the processor for the program's standard input, standard output, and standard error, with values such as pipe, file descriptor, and none. The default value is None.
- After obtaining the output, Pingp.stdout (<open file ' <fdopen> ', Mode ' RB ' >) becomes a readable file object that can be read using the corresponding file manipulation function.
From the output alone, the output of example 2 and Example 3 is the same. However, the two are completely different. In Example 2, the output of the child process is not controlled. In Example 3, the output of its child processes is collected. If you comment out the phrase "print(PingP.stdout.read ())" in the script, the program output is as follows:
d:\workspace\python\python3\practise\subprocess>python3 demo01.py154040
Another way is to use the communicate method provided by the Popen class. Examples such as the following
# !/usr/bin/env python Import = subprocess. Popen (['cat','/etc/passwd'],stdout== Subprocess. Popen (['grep','root'],stdin=ch1.stdout, stdout== ch2.communicate ()print(res)
The output is:
('root:x:0:0:root:/root:/bin/bash\n', None)
Subprocess. Pipe actually provides a buffer for text flow. The CH1 stdout the text out to the buffer, and then CH2 's stdin reads the text from the pipe. The output text of the CH2 is also stored in the pipe until the communicate () method reads the text from the pipe.
The communicate () method returns a tuple (Stdout,sterr). It is important to note thatcommunicate () is a method of the Popen object that blocks the parent process until the child process finishes. Also, because the data is cached in memory, do not use this method if the data is large.
Managing processes using the SUBPROCESSM module