subprocess.check_output和stdout有什么不同 还有run和popen

subprocess 模块提供了多种方法来运行外部命令,并且可以捕获标准输出、标准错误等。以下是 subprocess.check_outputstdout 参数、subprocess.runsubprocess.Popen 的区别和用途:

1. subprocess.check_output

  • 用途 :运行命令并捕获标准输出(stdout)的输出。

  • 行为

    • 如果命令成功(退出码为 0),它会返回标准输出的内容。

    • 如果命令失败(退出码非 0),它会抛出一个 subprocess.CalledProcessError 异常。

  • 优点

    • 简单易用,直接返回输出内容。

    • 异常处理,方便调试。

  • 示例

    复制代码
    try:
        output = subprocess.check_output(["echo", "Hello, World!"])
        print(output.decode())  # 输出为 bytes,需要解码
    except subprocess.CalledProcessError as e:
        print(f"Error: {e}")

2. stdout 参数

  • 用途

    • 用于指定 subprocess 中标准输出的去向。

    • 可以设置为:

      • subprocess.PIPE:将输出捕获到管道中。

      • subprocess.DEVNULL:丢弃输出。

      • sys.stdout:将输出直接打印到控制台。

  • 行为

    • 结合 subprocess.runsubprocess.Popen 使用。

    • 默认情况下,stdout 会打印到控制台。

  • 示例

    复制代码
    result = subprocess.run(["echo", "Hello, World!"], stdout=subprocess.PIPE, text=True)
    print(result.stdout)  # 捕获标准输出

3. subprocess.run

  • 用途:运行命令并等待其完成。

  • 行为

    • 返回一个 subprocess.CompletedProcess 对象。

    • 默认情况下,标准输出和标准错误会打印到控制台。

    • 可以通过参数(如 stdoutstderrcapture_output 等)控制输出和错误的处理。

  • 优点

    • 简洁且功能强大。

    • 可以控制命令的执行方式。

  • 示例

    复制代码
    # 默认输出到控制台
    subprocess.run(["echo", "Hello, World!"])
    
    # 捕获输出
    result = subprocess.run(["echo", "Hello, World!"], stdout=subprocess.PIPE, text=True)
    print(result.stdout)

4. subprocess.Popen

  • 用途:创建一个子进程并与其交互。

  • 行为

    • subprocess 模块的底层实现,提供了更多灵活性。

    • 可以通过管道与子进程进行交互(例如 stdinstdoutstderr)。

    • 需要手动调用 .wait() 等待子进程结束。

  • 优点

    • 灵活性高,适合复杂的交互场景。

    • 可以动态地与子进程交互。

  • 示例

    复制代码
    # 创建子进程
    process = subprocess.Popen(["echo", "Hello, World!"], stdout=subprocess.PIPE, text=True)
    
    # 与子进程交互
    output = process.communicate()[0]
    print(output)
    
    # 等待子进程结束
    process.wait()

总结对比

方法 输出捕获 异常处理 返回类型 灵活性 用途
subprocess.check_output 字节或字符串 最低 简单获取标准输出
stdout 参数 需通过上下文获取 结合其他方法使用
subprocess.run 可选 CompletedProcess 通用命令执行
subprocess.Popen 可选 Popen 对象 最高 复杂交互场景

选择建议

  • 如果只需要捕获输出并处理异常,使用 subprocess.check_output

  • 如果需要更灵活的控制和交互,使用 subprocess.Popen

  • 如果只需要简单运行命令,使用 subprocess.run

有时候你使用check能打印输出但是获取不到文本信息 就只能使用popen或者run的stderr

复制代码
result = subprocess.run(
                command,
                check=True,
                stderr=subprocess.PIPE,
                text=True,
                encoding='utf-8'
            )
output = result.stderr
输入输出都要用这个去获取

那是因为他输出的不是在标准输出 是在stderr下

相关推荐
考虑考虑2 小时前
Mybatis实现批量插入
java·后端·mybatis
咖啡八杯3 小时前
GoF设计模式——中介者模式
java·后端·spring·设计模式
青石路7 小时前
记一次多JDK版本问题的排查,一坑套一坑,差点没爬上来
java
像我这样帅的人丶你还10 小时前
Java 后端详解(五):Redis 缓存
java·后端·全栈
plainGeekDev12 小时前
GreenDAO → Room
android·java·kotlin
jiayou6413 小时前
KingbaseES 表级与列级加密完全指南
数据库·后端
亦暖筑序17 小时前
Java 8老系统AI Workflow实战:把一次性AI对话升级成可恢复工作流
java·后端
敲代码的彭于晏17 小时前
Bean 生命周期完全图解:前端同学也能看懂的 Spring 核心机制
java·前端·后端
plainGeekDev19 小时前
ButterKnife → ViewBinding
android·java·kotlin
GBASE1 天前
G术时刻 |GBase 8s数据库事务并发控制之封锁技术介绍(下)
数据库