详细介绍一下subprocess是个什么库?

2025-08-16 21:37:09 2 分享链接 开发笔记 python

subprocess 是 Python 标准库中用于创建新进程、连接到它们的输入/输出/错误管道,并获取它们的返回码的模块。它提供了一种灵活的方式来在 Python 程序中执行外部命令(如 ffmpeglscmd 等),是替代旧有模块(如 os.systemos.popen)的推荐方案。

核心功能

subprocess 的主要作用是让 Python 程序与外部命令/程序进行交互,具体包括:

  1. 执行外部命令(如调用 ffmpeg 处理视频、git 执行版本控制等)。
  2. 获取命令的输出结果(stdout)、错误信息(stderr)。
  3. 向外部命令传递输入(stdin)。
  4. 控制命令的执行环境(如工作目录、环境变量)。
  5. 等待命令执行完成并获取返回码(判断命令是否成功执行)。

常用函数

subprocess 模块提供了多个函数,其中最常用的有:

1. subprocess.run()(推荐)

Python 3.5+ 新增,是执行命令的主要函数,封装了其他低级函数的功能,返回一个 CompletedProcess 对象(包含命令执行结果)。

基本用法

import subprocess

# 执行简单命令(如查看当前目录)
result = subprocess.run(['ls', '-l'],  # 命令及其参数(列表形式推荐,避免空格问题)
                        stdout=subprocess.PIPE,  # 捕获标准输出
                        stderr=subprocess.PIPE,  # 捕获标准错误
                        text=True)  # 输出以字符串形式返回(默认是字节流)

# 查看结果
print("返回码:", result.returncode)  # 0 表示成功,非0表示失败
print("标准输出:", result.stdout)
print("标准错误:", result.stderr)

关键参数

  • args:要执行的命令(可以是字符串或列表,推荐列表形式,避免解析问题)。
  • stdout/stderr:控制输出的处理方式:

    • subprocess.PIPE:捕获输出到 result.stdout/result.stderr
    • subprocess.DEVNULL:忽略输出。
    • subprocess.STDOUT:将 stderr 合并到 stdout。
  • text(或 universal_newlines):设为 True 时,输出为字符串(否则为字节流)。
  • check:设为 True 时,若命令返回非0状态码,会抛出 CalledProcessError 异常(常用于确保命令必须成功执行的场景)。
  • cwd:指定命令执行的工作目录。
  • env:指定环境变量(默认继承当前进程的环境变量)。

2. 其他函数(了解即可)

  • subprocess.call():类似 run(),但只返回命令的返回码(不捕获输出)。
  • subprocess.check_call():类似 call(),但命令失败时会抛出异常(等价于 run(..., check=True))。
  • subprocess.check_output():专门用于获取命令输出,命令失败时抛出异常(等价于 run(..., check=True, stdout=PIPE).stdout)。

在视频处理脚本中的应用

在之前的视频处理脚本中,subprocess.run() 主要用于:

  1. 调用 ffmpeg -encoders 检测系统支持的编码器(判断硬件编码能力)。
  2. 调用 ffmpeg 命令处理视频(应用滤镜、编码转换等)。

例如,执行 ffmpeg 处理视频的核心代码:

# 构建ffmpeg命令(列表形式)
ffmpeg_cmd = [
    'ffmpeg', '-i', input_path,  # 输入文件
    '-vf', vf_filter,  # 应用滤镜
    '-r', '60',  # 帧率
    output_path  # 输出文件
]

# 执行命令并捕获结果
result = subprocess.run(
    ffmpeg_cmd,
    check=True,  # 命令失败时抛出异常
    stdout=subprocess.PIPE,  # 捕获输出
    stderr=subprocess.PIPE,  # 捕获错误
    text=True  # 输出为字符串
)

为什么用 subprocess 而不是 os.system

  • 安全性os.system 会直接将命令字符串传递给shell解析,存在注入风险(如命令包含 ; rm -rf / 等恶意代码);而 subprocess 推荐使用列表形式传递命令,避免解析问题。
  • 灵活性subprocess 可以精细控制输入/输出、超时时间、环境变量等,而 os.system 功能简单,无法捕获输出。
  • 可读性subprocess.run() 的参数更明确,代码意图更清晰。

总结

subprocess 是 Python 中执行外部命令的核心模块,尤其适合需要与系统工具(如 ffmpeggitbash 等)交互的场景。其设计灵活且安全,run() 函数是大多数情况下的首选,通过控制参数可以满足各种命令执行需求。

详细介绍一下subprocess是个什么库?