table of Contents
1. os.system() function example
2. os.popen() function example
3. Examples of commands.getstatusoutput() function
1. Common functions in the subprocess module
2. The definition and parameter description of the above functions
3. Introduction to the subprocess.CompletedProcess class
Three, subprocess.Popen introduction
1. The constructor of subprocess.Popen
2. Methods that can be called by instances of the subprocess.Popen class
3. Examples of using subprocess.Popen
We can interact with the operating system through command line instructions on almost any operating system, such as the shell under the Linux platform. So how do we use Python to complete the execution of these command line instructions? In addition, what we should know is that the execution of command-line instructions usually has two results that we are more concerned about:
- The status code of the command execution--indicating whether the command execution is successful
- The output result of the command execution-the output after the command is executed successfully
In the early Python version, we mainly used os.system(), os.popen().read() and other functions to execute command-line instructions, and there is also a commands module that is rarely used. However, the subprocess module is recommended in the official documentation starting from Python 2.4, so the related functions of the os module and the commands module are only provided here as a simple example of use. The important thing we want to introduce is the subprocess module.
One, os and commands module
Python provides the following functions to help us complete the execution of command line instructions:
Function name | description |
---|---|
os.system(command) | Return the command execution status code, and output the command execution result to the screen |
os.popen(command).read() | The command execution result can be obtained, but the command execution status code cannot be obtained |
commands.getstatusoutput(command) | Return a tuple (command execution status code, command execution result), only exists in Python 2.7, and does not support windows platform |
Description:
- The os.popen(command) function gets a file object, so in addition to the read() method, it also supports write() and other methods, depending on the command;
- The commands module only exists in Python 2.7 and does not support the windows platform, so the commands module is rarely used. In addition, the commands module is actually completed by encapsulating os.popen().
1. os.system() function example
>>> import os
>>>
>>> retcode = os.system('dir')
驱动器 C 中的卷没有标签。
卷的序列号是 4C32-B292
C:\Users\wader\PycharmProjects\LearnPython 的目录
2017/03/21 11:15 <DIR> .
2017/03/21 11:15 <DIR> ..
2017/07/29 18:04 <DIR> .idea
2016/12/06 11:19 <DIR> blog
2016/12/06 11:42 <DIR> day01
2016/12/09 22:07 <DIR> day02
2017/01/04 09:14 <DIR> day03
2017/07/19 16:11 <DIR> day04
2017/07/29 14:44 <DIR> day05
2017/07/06 14:45 <DIR> day06
2017/07/06 17:13 <DIR> exam01
0 个文件 0 字节
11 个目录 6,659,977,216 可用字节
>>> retcode
0
>>>
2. os.popen() function example
>>> import os
>>>
>>> ret = os.popen('dir').read()
>>> print(ret)
驱动器 C 中的卷没有标签。
卷的序列号是 4C32-B292
C:\Users\wader\PycharmProjects\LearnPython 的目录
2017/03/21 11:15 <DIR> .
2017/03/21 11:15 <DIR> ..
2017/07/29 18:04 <DIR> .idea
2016/12/06 11:19 <DIR> blog
2016/12/06 11:42 <DIR> day01
2016/12/09 22:07 <DIR> day02
2017/01/04 09:14 <DIR> day03
2017/07/19 16:11 <DIR> day04
2017/07/29 14:44 <DIR> day05
2017/07/06 14:45 <DIR> day06
2017/07/06 17:13 <DIR> exam01
0 个文件 0 字节
11 个目录 6,664,052,736 可用字节
>>>
3. Examples of commands.getstatusoutput() function
It should be noted that the commands module does not support the windows platform, so this example is executed under the Linux platform
>>> import os
>>> os.system('ls')
cmdline-jmxclient-0.10.3.jar dhparam.pem FtpMan.class gitlab.crt gitlab.csr gitlab.key resolv.txt test.json test.php test.sh test.text test.txt
0
>>> import commands
>>> retcode, ret = commands.getstatusoutput('ls -l')
>>> retcode
0
>>> print(ret)
total 68
-rw-r--r-- 1 root root 20124 Jul 11 2016 cmdline-jmxclient-0.10.3.jar
-rw-r--r-- 1 root root 424 Aug 22 2016 dhparam.pem
-rw-r--r-- 1 root root 2576 Jul 13 2016 FtpMan.class
-rw-r--r-- 1 root root 1302 Aug 22 2016 gitlab.crt
-rw-r--r-- 1 root root 1054 Aug 22 2016 gitlab.csr
-rw-r--r-- 1 root root 1675 Aug 22 2016 gitlab.key
-rw-r--r-- 1 root root 9329 Jun 24 2016 resolv.txt
-rw-r--r-- 1 root root 594 Mar 7 08:14 test.json
-rw-r--r-- 1 root root 162 Jun 28 10:39 test.php
-rw-r--r-- 1 root root 760 Jun 24 2016 test.sh
-r-x------ 1 root root 0 Feb 6 08:21 test.text
drwxr-xr-x 2 root root 4096 Feb 7 16:43 test.txt
>>>
By looking at the attributes provided by the commands module, it can be seen that it also provides a separate function to obtain the status code and execution result of the command execution, as shown below:
>>> dir(commands)
['__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'getoutput', 'getstatus', 'getstatusoutput', 'mk2arg', 'mkarg']
Two, subprocess module
Subprocess is a new module in Python 2.4, which allows you to spawn new processes, connect to their input/output/error pipelines, and get their return (status) codes. The purpose of this module is to replace several old modules and methods, such as:
- os.system
- os.spawn*
1. Common functions in the subprocess module
function | description |
---|---|
subprocess.run() | Functions added in Python 3.5. Execute the specified command, wait for the completion of the command execution, and return an instance of the CompletedProcess class containing the execution result . |
subprocess.call() | Execute the specified command and return the command execution status code , its function is similar to os.system(cmd). |
subprocess.check_call() | Functions added in Python 2.5. Execute the specified command, and return the status code if the execution is successful , otherwise throw an exception . Its function is equivalent to subprocess.run(..., check=True). |
subprocess.check_output() | Functions added in Python 2.7. Execute the specified command, if the execution status code is 0, the command execution result will be returned , otherwise an exception will be thrown . |
subprocess.getoutput(cmd) | Receives commands in string format, executes the commands and returns the execution results . Its function is similar to os.popen(cmd).read() and commands.getoutput(cmd). |
subprocess.getstatusoutput(cmd) | Execute cmd command and return a tuple (command execution status, command execution result output) , its function is similar to commands.getstatusoutput(). |
Description:
- In versions after Python 3.5, the official document advocates subprocess.run() function instead of other functions to use the function of the subproccess module;
- In versions before Python 3.5, we can use the functions of the subprocess module through subprocess.call(), subprocess.getoutput() and other functions listed above;
- subprocess.run(), subprocess.call(), subprocess.check_call() and subprocess.check_output() are all advanced functions implemented by encapsulating subprocess.Popen, so if we need more complex functions, we can use subprocess .Popen to complete.
- The subprocess.getoutput() and subprocess.getstatusoutput() functions are two legacy functions from the commands module of Python 2.x. They implicitly call the system shell, and do not guarantee the security and exception handling consistency of other functions. In addition, they only support the Windows platform since Python 3.3.4.
2. The definition and parameter description of the above functions
Function parameter list:
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, timeout=None, check=False, universal_newlines=False)
subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None)
subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None)
subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False, timeout=None)
subprocess.getstatusoutput(cmd)
subprocess.getoutput(cmd)
Parameter Description:
- args: The shell command to be executed . The default should be a sequence of strings, such as ['df','-Th'] or ('df','-Th'), or a string, such as'df- Th', but at this time you need to set the value of the shell parameter to True.
- shell: If the shell is True, the specified command will be executed through the shell . This is very useful if we need to access certain shell features, such as pipes, file name wildcards, and environment variable expansion functions. Of course, python itself also provides the implementation of many shell-like features, such as glob, fnmatch, os.walk(), os.path.expandvars(), os.expanduser() and shutil.
- check: If the value of the check parameter is True and the process executing the command exits with a non-zero status code, a CalledProcessError exception will be thrown , and the exception object will contain the parameters, exit status code, and stdout and stderr (if they If it is captured).
- stdout, stderr:
- The run() function does not capture the normal output and error output of the command execution result by default. If we need to pass subprocess.PIPE to obtain these contents, then we can pass the stdout and stderr attributes of the returned CompletedProcess class instance or capture the corresponding contents;
- The call() and check_call() functions return the status code of the command execution, not the CompletedProcess class instance, so for them, stdout and stderr are not suitable for assignment to subprocess.PIPE;
- The check_output() function will return the command execution result by default, so there is no need to set the value of stdout. If we want to capture error information in the result, we can execute stderr=subprocess.STDOUT.
- input: This parameter is passed to Popen.communicate(), usually the value of this parameter must be a byte sequence, if universal_newlines=True, its value should be a string.
- universal_newlines: This parameter affects the data format of input and output. For example, its value is False by default. At this time, the output of stdout and stderr is a byte sequence; when the value of this parameter is set to True, the output of stdout and stderr is String.
3. Introduction to the subprocess.CompletedProcess class
It should be noted that the subprocess.run() function is a new advanced function in Python 3.5, and its return value is an instance of the subprocess.CompletedPorcess class. Therefore, the subprocess.completedPorcess class also exists in Python 3.5. It represents the status information of a finished process, and the attributes it contains are as follows:
- args: used to load the parameters of the process, this may be a list or a string
- returncode: The exit status code of the child process. Under normal circumstances, an exit status code of 0 indicates that the process has run successfully; a negative value -N indicates that the child process was terminated by signal N
- stdout: stdout captured from the child process. This is usually a sequence of bytes. If universal_newlines=True is specified when the run() function is called, the attribute value is a string. If stderr=subprocess.STDOUT is specified when the run() function is called, then stdout and stderr will be integrated into this attribute, and stderr will be None
- stderr: stderr captured from the child process. Its value is the same as stdout, a byte sequence or a string. If stderr is captured, its value is None
- check_returncode(): If the returncode is a non-zero value, this method will throw a CalledProcessError exception.
4. Examples
subprocess.run()
>>> subprocess.run(["ls", "-l"]) # doesn't capture output
CompletedProcess(args=['ls', '-l'], returncode=0)
>>> subprocess.run("exit 1", shell=True, check=True)
Traceback (most recent call last):
...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1
>>> subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE)
CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0,
stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n')
subprocess.call()
>>> subprocess.call(['ls', '-l'])
总用量 160
drwxr-xr-x 2 wader wader 4096 12月 7 2015 公共的
drwxr-xr-x 2 wader wader 4096 12月 7 2015 模板
drwxr-xr-x 2 wader wader 4096 12月 7 2015 视频
drwxr-xr-x 2 wader wader 4096 12月 7 2015 图片
drwxr-xr-x 2 wader wader 4096 12月 7 2015 文档
drwxr-xr-x 2 wader wader 4096 4月 13 2016 下载
drwxr-xr-x 2 wader wader 4096 12月 7 2015 音乐
drwxr-xr-x 7 wader wader 4096 5月 26 2016 桌面
0
>>> subprocess.call('ls -l', shell=True)
总用量 160
drwxr-xr-x 2 wader wader 4096 12月 7 2015 公共的
drwxr-xr-x 2 wader wader 4096 12月 7 2015 模板
drwxr-xr-x 2 wader wader 4096 12月 7 2015 视频
drwxr-xr-x 2 wader wader 4096 12月 7 2015 图片
drwxr-xr-x 2 wader wader 4096 12月 7 2015 文档
drwxr-xr-x 2 wader wader 4096 4月 13 2016 下载
drwxr-xr-x 2 wader wader 4096 12月 7 2015 音乐
drwxr-xr-x 7 wader wader 4096 5月 26 2016 桌面
0
>>> subprocess.call(['ls', '-l'], stdout=subprocess.DEVNULL)
0
>>> subprocess.call(['ls', '-l', '/test'])
ls: 无法访问/test: 没有那个文件或目录
2
suprocess.check_call()
>>> subprocess.check_call(['ls', '-l'])
总用量 160
drwxr-xr-x 2 wader wader 4096 12月 7 2015 公共的
drwxr-xr-x 2 wader wader 4096 12月 7 2015 模板
drwxr-xr-x 2 wader wader 4096 12月 7 2015 视频
drwxr-xr-x 2 wader wader 4096 12月 7 2015 图片
drwxr-xr-x 2 wader wader 4096 12月 7 2015 文档
drwxr-xr-x 2 wader wader 4096 4月 13 2016 下载
drwxr-xr-x 2 wader wader 4096 12月 7 2015 音乐
drwxr-xr-x 7 wader wader 4096 5月 26 2016 桌面
0
>>> subprocess.check_call('ls -l', shell=True)
总用量 160
drwxr-xr-x 2 wader wader 4096 12月 7 2015 公共的
drwxr-xr-x 2 wader wader 4096 12月 7 2015 模板
drwxr-xr-x 2 wader wader 4096 12月 7 2015 视频
drwxr-xr-x 2 wader wader 4096 12月 7 2015 图片
drwxr-xr-x 2 wader wader 4096 12月 7 2015 文档
drwxr-xr-x 2 wader wader 4096 4月 13 2016 下载
drwxr-xr-x 2 wader wader 4096 12月 7 2015 音乐
drwxr-xr-x 7 wader wader 4096 5月 26 2016 桌面
0
>>> subprocess.check_call('ls -l /test', shell=True)
ls: 无法访问/test: 没有那个文件或目录
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.4/subprocess.py", line 557, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command 'ls -l /test' returned non-zero exit status 2
sbuprocess.check_output()
>>> ret = subprocess.check_output(['ls', '-l'])
>>> print(ret)
b' \xe5\x85\xac\xe5\x85\xb1\xe7\x9a\x84\ndrwxr-xr-x 2 wader wader 4096 12\xe6\x9c\x88 7 2015 \xe6\xa8\xa1\xe6\x9d\xbf\ndrwxr-xr-x 2 wader wader 4096 12\xe6\x9c\x88 7 2015 \xe8\xa7\x86\xe9\xa2\x91\ndrwxr-xr-x 2 wader wader 4096 12\xe6\x9c\x88 7 2015 \xe5\x9b\xbe\xe7\x89\x87\ndrwxr-xr-x 2 wader wader 4096 12\xe6\x9c\x88 7 2015 \xe6\x96\x87\xe6\xa1\xa3\ndrwxr-xr-x 2 wader wader 4096 4\xe6\x9c\x88 13 2016 \xe4\xb8\x8b\xe8\xbd\xbd\ndrwxr-xr-x 2 wader wader 4096 12\xe6\x9c\x88 7 2015 \xe9\x9f\xb3\xe4\xb9\x90\ndrwxr-xr-x 7 wader wader 4096 5\xe6\x9c\x88 26 2016 \xe6\xa1\x8c\xe9\x9d\xa2\n'
>>> ret = subprocess.check_output(['ls', '-l'], universal_newlines=True)
>>> print(ret)
总用量 160
drwxr-xr-x 2 wader wader 4096 12月 7 2015 公共的
drwxr-xr-x 2 wader wader 4096 12月 7 2015 模板
drwxr-xr-x 2 wader wader 4096 12月 7 2015 视频
drwxr-xr-x 2 wader wader 4096 12月 7 2015 图片
drwxr-xr-x 2 wader wader 4096 12月 7 2015 文档
drwxr-xr-x 2 wader wader 4096 4月 13 2016 下载
drwxr-xr-x 2 wader wader 4096 12月 7 2015 音乐
drwxr-xr-x 7 wader wader 4096 5月 26 2016 桌面
subprocess.getoutput()与subprocess.getstatusoutput()
>>> ret = subprocess.getoutput('ls -l')
>>> print(ret)
总用量 160
drwxr-xr-x 2 wader wader 4096 12月 7 2015 公共的
drwxr-xr-x 2 wader wader 4096 12月 7 2015 模板
drwxr-xr-x 2 wader wader 4096 12月 7 2015 视频
drwxr-xr-x 2 wader wader 4096 12月 7 2015 图片
drwxr-xr-x 2 wader wader 4096 12月 7 2015 文档
drwxr-xr-x 2 wader wader 4096 4月 13 2016 下载
drwxr-xr-x 2 wader wader 4096 12月 7 2015 音乐
drwxr-xr-x 7 wader wader 4096 5月 26 2016 桌面
>>> retcode, output = subprocess.getstatusoutput('ls -l')
>>> print(retcode)
0
>>> print(output)
总用量 160
drwxr-xr-x 2 wader wader 4096 12月 7 2015 公共的
drwxr-xr-x 2 wader wader 4096 12月 7 2015 模板
drwxr-xr-x 2 wader wader 4096 12月 7 2015 视频
drwxr-xr-x 2 wader wader 4096 12月 7 2015 图片
drwxr-xr-x 2 wader wader 4096 12月 7 2015 文档
drwxr-xr-x 2 wader wader 4096 4月 13 2016 下载
drwxr-xr-x 2 wader wader 4096 12月 7 2015 音乐
drwxr-xr-x 7 wader wader 4096 5月 26 2016 桌面
>>> retcode, output = subprocess.getstatusoutput('ls -l /test')
>>> print(retcode)
2
>>> print(output)
ls: 无法访问/test: 没有那个文件或目录
Three, subprocess.Popen introduction
This class is used to execute a subroutine in a new process. As we mentioned earlier, these functions introduced above are implemented based on the subprocess.Popen class, and some common requirements can be fulfilled in many aspects by using these encapsulated advanced functions. Since the process creation and management at the bottom of the subprocess module are handled by the Popen class, when we cannot use the above advanced functions to achieve some less common functions, we can use the flexible api provided by the subprocess.Popen class to complete .
1. The constructor of subprocess.Popen
class subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None,
preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=False,
startup_info=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=())
Parameter Description:
- args: The shell command to be executed , which can be a string or a sequence of parameters of the command. When the value of the parameter is a string, the interpretation process of the command is platform-dependent, so it is usually recommended to pass the args parameter as a sequence.
- bufsize: Specify the cache strategy, 0 means no buffering, 1 means line buffering, other numbers greater than 1 mean the buffer size, and negative numbers mean using the system default buffering strategy.
- stdin, stdout, stderr: respectively represent the program standard input, output, and error handle .
- preexec_fn: used to specify an executable object that will be called before the child process runs, only valid on Unix platforms.
- close_fds: If the value of this parameter is True, all file descriptors except 0, 1 and 2 will be closed before the child process is executed.
- shell: This parameter is used to identify whether to use the shell as the program to be executed. If the shell value is True, it is recommended to pass the args parameter as a string instead of as a sequence .
- cwd: If the parameter value is not None, the function will change the current working directory before executing this subprocess.
- env: Used to specify the environment variables of the child process. If env=None, the environment variables of the child process will be inherited from the parent process. If env!=None, its value must be a mapping object.
- universal_newlines: If the parameter value is True, the stdin, stdout and stderr of the file object will be opened as a text stream, otherwise they will be opened as a binary stream.
- startupinfo and creationflags: These two parameters are only valid under Windows. They will be passed to the underlying CreateProcess() function to set some attributes of the child process, such as the appearance of the main window, process priority, etc.
2. Methods that can be called by instances of the subprocess.Popen class
method | description |
---|---|
Popen.poll() | It is used to check whether the subprocess (command) has been executed , it returns None if it is not finished, and returns a status code after it ends. |
Popen.wait(timeout=None) | Wait for the end of the child process and return the status code; if the process has not ended after the number of seconds specified by timeout, a TimeoutExpired exception will be thrown. |
Popen.communicate(input=None, timeout=None) | This method can be used to interact with the process, such as sending data to stdin, reading data from stdout and stderr, until the end of the file is reached. |
Popen.send_signal(signal) | Send the specified signal to this child process. |
Popen.terminate() | Stop the child process. |
Popen.kill() | Kill the child process. |
A description of the communicate() method:
- The optional parameter input in this method should be the data to be sent to the child process, or if no data is sent to the child process, the parameter should be None. The data type of the input parameter must be a byte string. If the universal_newlines parameter value is True, the data type of the input parameter must be a string.
- This method returns a tuple (stdout_data, stderr_data) , these data will be bytes or strings (if the value of universal_newlines is True).
- If the process has not ended after the number of seconds specified by timeout, a TimeoutExpired exception will be thrown. Catch this exception and try to communicate again without losing any output data. But the child process is not killed after the timeout. In order to clear the corresponding content reasonably, a good application should manually kill the child process to end the communication.
- It should be noted that the data read here is buffered in memory, so if the data size is very large or unlimited, this method should not be used.
3. Examples of using subprocess.Popen
Example 1:
>>> import subprocess
>>>
>>> p = subprocess.Popen('df -Th', stdout=subprocess.PIPE, shell=True)
>>> print(p.stdout.read())
Filesystem Type Size Used Avail Use% Mounted on
/dev/vda1 ext4 40G 12G 26G 31% /
devtmpfs devtmpfs 3.9G 0 3.9G 0% /dev
tmpfs tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs tmpfs 3.9G 386M 3.5G 10% /run
tmpfs tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
tmpfs tmpfs 783M 0 783M 0% /run/user/0
tmpfs tmpfs 783M 0 783M 0% /run/user/1000
Example 2:
>>> obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> obj.stdin.write('print(1) \n')
>>> obj.stdin.write('print(2) \n')
>>> obj.stdin.write('print(3) \n')
>>> out,err = obj.communicate()
>>> print(out)
1
2
3
>>> print(err)
Example 3:
>>> obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> out,err = obj.communicate(input='print(1) \n')
>>> print(out)
1
>>> print(err)
Example 4:
Realizing df -Th | grep data
the function of similar commands is actually realizing the common function of the pipeline in the shell.
>>>
>>> p1 = subprocess.Popen(['df', '-Th'], stdout=subprocess.PIPE)
>>> p2 = subprocess.Popen(['grep', 'data'], stdin=p1.stdout, stdout=subprocess.PIPE)
>>> out,err = p2.communicate()
>>> print(out)
/dev/vdb1 ext4 493G 4.8G 463G 2% /data
/dev/vdd1 ext4 1008G 420G 537G 44% /data1
/dev/vde1 ext4 985G 503G 432G 54% /data2
>>> print(err)
None
def sync_call(cmd, chdir):
os.chdir(chdir)
p = subprocess.Popen(
cmd,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
out, err = p.communicate()
if p.returncode == 0 or p.returncode is None:
flag = True
else:
flag = False
return flag, out.decode() # out.decode(返回的是cmd命令运行过程中输出的内容)
Four, summary
So which module and function should we use to execute commands to interact with the system and the system? Let's make a summary below:
- The first thing you should know is that the Python 2.4 version introduced the subprocess module to replace os.system(), os.popen(), os.spawn*() and other functions and the commands module; that is to say, if you are using Python Version 2.4 and above should use the subprocess module.
- If your application uses Python 2.4 or higher, but Python 3.5 or lower, the official recommendation from Python is to use the subprocess.call() function. A subprocess.check_call() function has been added in Python 2.5, and a subprocess.check_output() function has been added in Python 2.7. These two functions can also be used as required.
- If your application uses Python 3.5 and above (it should be rare at the moment), the official advice given by Python is to use the subprocess.run() function as much as possible.
- When the advanced functions of subprocess.call(), subprocess.check_call(), subprocess.check_output() and subprocess.run() cannot meet the needs, we can use the subprocess.Popen class to implement the complex functions we need.