The subprocess module allows us to start a new process and connect to their input/output/error pipes, thereby obtaining the return value.
Using the subprocess module
The subprocess module first recommends using its run method; for more advanced usage, you can directly use the Popen interface.
The syntax of the run method is as follows:
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, capture_output=False, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None, universal_newlines=None)
- args: Indicates the command to be executed. It must be a string or a list of string parameters.
- stdin, stdout and stderr: The standard input, output, and error of the child process. Their values can be subprocess.PIPE, subprocess.DEVNULL, an existing file descriptor, an already opened file object, or None. subprocess.PIPE indicates creating a new pipe for the child process. subprocess.DEVNULL indicates using os.devnull. The default is None, meaning nothing is done. Additionally, stderr can be merged into stdout for output together.
- timeout: Sets the command timeout time. If the command execution time exceeds the timeout, the child process will be killed and a TimeoutExpired exception will be raised.
- check: If this parameter is set to True and the process exit status code is not 0, a CalledProcessError exception will be raised.
- encoding: If this parameter is specified, stdin, stdout, and stderr can receive string data and encode it with that encoding. Otherwise, only bytes-type data is accepted.
- shell: If this parameter is True, the specified command will be executed through the operating system's shell.
The run method call returns a CompletedProcess instance. It is similar to directly using Popen; the implementation is the same. In fact, it also calls Popen, and is roughly the same as the Popen constructor, for example:
Example
>>> subprocess.run(["ls", "-l", "/dev/null"])
crw-rw-rw- 1 root wheel 3, 2 5 4 13:34 /dev/null
CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0)
returncode: The status of the executed child process. Usually a return status of 0 indicates that it has finished running. If the value is a negative value '-N', it indicates that the child process was terminated.
Simple example:
Example
def runcmd(command):
ret = subprocess.run(command,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,encoding="utf-8",timeout=1)
if ret.returncode == 0:
print("success:",ret)
else:
print("error:",ret)
runcmd(["dir","/b"])#Sequence argument
runcmd("exit 1")#String argument
The output result is as follows:
success: CompletedProcess(args=['dir', '/b'], returncode=0, stdout='test.py\n', stderr='') error: CompletedProcess(args='exit 1', returncode=1, stdout='', stderr='')
Popen() method
Popen is the core of subprocess; the creation and management of child processes are handled by it.
Constructor:
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, startupinfo=None, creationflags=0,restore_signals=True, start_new_session=False, pass_fds=(), *, encoding=None, errors=None)
Common parameters:
- args: Shell command, which can be a string or a sequence type (e.g., list, tuple)
- bufsize: Buffer size. Used when creating pipe objects for standard streams. Default is -1.
0: No buffering
1: Line buffering, only available when universal_newlines=True, that is, text mode
Positive number: Indicates the buffer size
Negative number: Indicates to use the system default buffer size. - stdin, stdout, stderr: Respectively represent the program's standard input, output, and error handles
- preexec_fn: Only valid on Unix platforms. It is used to specify a callable object, which will be called before the child process runs.
- shell: If this parameter is True, the specified command will be executed through the operating system's shell.
- cwd: Used to set the current directory of the child process.
- env: Used to specify the environment variables of the child process. If env=None, the child process's environment variables will be inherited from the parent process.
Create a child process, then execute a simple command:
Example
>>> p = subprocess.Popen('ls -l', shell=True)
>>> total 164
-rw-r--r-- 1 root root 133 Jul 4 16:25 admin-openrc.sh
-rw-r--r-- 1 root root 268 Jul 10 15:55 admin-openrc-v3.sh
...
>>> p.returncode
>>> p.wait()
0
>>> p.returncode
You can also usep = subprocess.Popen(['ls', '-cl'])to create a child process.
Popen object methods
- poll(): Checks whether the process has terminated. If terminated, returns returncode; otherwise, returns None.
- wait(timeout): Waits for the child process to terminate.
- communicate(input,timeout): Interacts with the child process, sending and reading data.
- send_signal(signal): Sends a signal to the child process.
- terminate(): Stops the child process, that is, sends the SIGTERM signal to the child process.
- kill(): Kills the child process. Sends the SIGKILL signal to the child process.
Example
import subprocess
def cmd(command):
subp = subprocess.Popen(command,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,encoding="utf-8")
subp.wait(2)
if subp.poll() == 0:
print(subp.communicate()[1])
else:
print("Failed")
cmd("java -version")
cmd("exit 1")
The output result is as follows:
java version "1.8.0_31" Java(TM) SE Runtime Environment (build 1.8.0_31-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode) 失败
Reference article:
https://blog.csdn.net/weixin_42547344/article/details/80894760
https://blog.csdn.net/maosijunzi/article/details/80138458