Calling external processes in Python is a common requirement, and here are a few common ways to do it.

os.system

This method actually calls the system C function system(), which is passed in as a string and executed in the system subshell as it would in the real shell.

Advantages: You can use shell features such as piping and redirection to implement complex commands.

import os

# Pipe all Java processes and kill them forcibly
os.system('ps -ef|grep java|cut -c 9-15|xargs kill -9')

Get all PNG image file names in the current directory and redirect them to png_list.txt
os.system('ls *.png > png_list.txt')
Copy the code

Disadvantages: The output of an external process cannot be captured by Python code, the system function only returns an exit status, and the string passed as a command must be a valid command, otherwise unexpected results will occur.

os.popen

Unlike the previous method, os.popen opens a pipe and returns the output to the caller through a file-like object, similar to the file-manipulation method open in Python.

import os

with os.popen('ls *.png', mode='r') as res:
    result = res.read()
Copy the code

subprocess.Popen

Popen ¶ This is the Popen class in Python’s subprocess library, which has more optional arguments as an alternative to os.popen.

import subprocess

Posix-class systems will call /bin/sh by default to execute the incoming command when shell=True
result = subprocess.Popen(['ls'.'-l'], shell=True, stdout=subprocess.PIPE).stdout.read()
Copy the code

subprocess.call

This function has optional arguments similar to the Popen class, but waits for the child process to complete before returning a return code.

import subprocess

return_code = subprocess.call(['ls'.'-l'], shell=True)
Copy the code

subprocess.run

This function, available in python3.5 and later, has several very useful parameters to choose from, and returns a CompletedProcess object from which standard input and output can be obtained.

import subprocess

Execute in the shell and get standard output and errors
result = subprocess.run(['ls'.'-l'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Shlex library can be used to split instruction strings
# subprocess.run(shlex.split('ls -l))
print(result.stdout)
print(result.stderr)

# Check the return value and raise a CalledProcessError exception if the subroutine returns an error
result = subprocess.run(['ls'.'-l'],check=True)

It's a good practice to control the timing of external processes in a project by putting a TimeoutExpired exception up if the subroutine times out
result = subprocess.run(['sleep'.'5'], timeout=3)
Copy the code

fabric.operations

from fabric import operations

res = operations.local('ls -l', capture=True)

Run the command on the remote server, but you need to configure the login information in advance
res = operations.run('cmd')
Copy the code

Third-party module SH

It dynamically parses $PATH to execute binary commands. Instead of executing Python classes or functions, Python wraps executable commands in the system PATH, meaning that all commands in the system PATH can be executed.

Sh. Ls ('-l', '/data') sh.ifconfig() Count = sh.wc(sh.ls('-l'), '-l') # p = sh.find('-name', 'sh.py') _bg=True) # do something else.Copy the code

conclusion

I prefer to recommend the run function in the subprocess module of the official library, which is easy to use.

reference

Python calls external processes in several ways