python subprocess 执行Linux指令

定义一个可以执行command的function:

def execute(shell_command_str=None, timeout=None, encoding="utf-8", check=True):
    assert shell_command_str is not None, "Please enter a shell command."

    result = subprocess.run(shell_command_str, shell=True, timeout=timeout, encoding=encoding, text=None, check=check,
                            capture_output=True)
    # returncode = 0 表示执行成功,其他整数表示执行异常
    return result.returncode, result.stdout, result.stderr

一、subprocess模块

1、概述
subprocess 模块首先推荐使用的是它的 run 方法subprocess.run(),更高级的用法可以直接使用 Popen 接口subprocess.Popen()

2、优点

  • 安全性:与os.system相比,subprocess避免了shell注入攻击的风险。
  • 灵活性:subprocess可以与子进程的stdin、stdout和stderr流进行交互。
  • 功能丰富:它支持复杂的系统调用,如管道和重定向。

3、subprocess.run()
subprocess.run() 是 Python 3.5 引入的一个高级接口

  • 语法格式:

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:这是命令和参数的列表,其中命令是列表的第一个元素。如果 shell 参数设置为 True,args必须是一个字符串

stdin:可以是 None、一个已打开的文件描述符、一个现有的文件对象,或者 subprocess.PIPE。用于指定子进程的标准输入。

input:如果 stdin 参数是 PIPE,这个参数可以被用来传递一个字符串到子进程的标准输入。

stdout 和 stderr:这些参数与 stdin 类似,但它们控制的是标准输出和标准错误输出。它们也可以被设置为 None、一个文件描述符、一个现有的文件对象,或者 subprocess.PIPE。

capture_output:如果设置为 True,stdout 和 stderr 将会被捕获。这相当于设置 stdout=subprocess.PIPE 和 stderr=subprocess.PIPE。

shell:如果为 True,指定的命令将通过 shell 执行。

cwd:如果指定,子进程的当前工作目录将被改变到 cwd。

timeout:如果指定,且执行时间超过了这个值(以秒计),将会抛出 subprocess.TimeoutExpired 异常。

check:如果设置为 True,并且进程以非零状态码退出,将会抛出 subprocess.CalledProcessError 异常。

encoding 和 errors:指定如何解码从子进程输出的字节。只有当 stdout 或 stderr 被捕获时才有效。

text:一个简写的标志,用于设置 encoding='utf-8' 和 universal_newlines=True,它会将 stdout 和 stderr 的输出作为字符串处理。

env:指定子进程的环境变量。如果为 None,使用父进程的环境变量。

universal_newlines:如果为 True,stdin、stdout 和 stderr 将会作为文本流处理,类似于 text=True。

**other_popen_kwargs:你可以提供其他的关键字参数,这些参数将直接传递给 Popen 构造函数。
  • 例如:
import subprocess

# 执行命令并捕获输出
result = subprocess.run(['ls', '-l'], capture_output=True, text=True)

print(f"命令输出:\n{result.stdout}")
if result.stderr:
    print(f"命令错误输出:\n{result.stderr}")

4、subprocess.Popen()

  • 参数说明:
args: 和 run 函数相同。
bufsize:缓冲区大小,-1 表示使用系统默认缓冲区大小,0 表示不使用缓冲区,1 表示行缓冲。
executable:如果指定,将使用这个可执行文件来替换要执行的程序。
stdin, stdout, stderr, shell, cwd:与 run 函数相同。
preexec_fn:仅在 Unix 系统上有效)是一个可调用对象,它将在子进程运行之前被调用。
close_fds:如果为 True(默认值),在子进程中除了 0、1 和 2 之外所有的文件描述符都将被关闭。
env:用于指定环境变量。
shell:如果这个参数为 True,指定的命令将通过 shell 执行。

cwd:如果指定,子进程的工作目录将改变到 cwd。

env:用于指定子进程的环境变量。如果为 None,子进程会继承父进程的环境变量。

universal_newlines:(现在推荐使用 text 参数)如果为 True,stdin、stdout 和 stderr 将作为文本流(字符串)而不是字节流。

startupinfo 和 creationflags:这两个参数仅在 Windows 系统上有效,用于控制子进程的创建方式。

restore_signals:(仅在 Unix 系统上有效)如果为 True,在执行新程序前,将会恢复 Python 的信号处理为默认值。

start_new_session:(仅在 Unix 系统上有效)如果为 True,子进程将会在新的会话中启动。

pass_fds:(仅在 Unix 系统上有效)要传递给子进程的文件描述符。

encoding 和 errors:这些参数用于设置在解码和编码文本数据时使用的编码和错误处理方式。

text:一个用于设置编码为 "utf-8" 且 universal_newlines=True 的简化参数,这将会让 stdout 和 stderr 的输出作为字符串处理。
  • 例如:
import subprocess
 
process = subprocess.Popen(['ping', '-c', '4', 'example.com'], stdout=subprocess.PIPE, text=True)
stdout, stderr = process.communicate()
if not stderr:
    print(stdout)
else:
    raise stderr

posted @ 2024-08-19 10:22  二月雪  阅读(75)  评论(0编辑  收藏  举报