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

#Execute the ls -l /dev/null command
>>> 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

import subprocess
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

>>> import subprocess
>>> 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 time
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