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下

相关推荐
YOU OU7 小时前
Redis基础常识与命令
数据库·redis·缓存
腻害兔7 小时前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
码智社8 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
大郭鹏宇9 小时前
基于 LangGraph 构建智能分诊系统(一):项目概述与环境搭建
大数据·人工智能·microsoft·langchain
萧瑟余晖9 小时前
JDK 26 新特性详解
java·开发语言
Database_Cool_9 小时前
OLTP 和 OLAP 区别详解:分析型数据库和事务型数据库怎么选(附阿里云 AnalyticDB MySQL 选型指南)
数据库·mysql·阿里云
爱写代码的阿森10 小时前
鸿蒙三方库 | harmony-utils之KvUtil键值型数据库操作详解
数据库·华为·harmonyos·鸿蒙·huawei
马优晨10 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
Database_Cool_10 小时前
单机 MySQL 迁移到分布式数据库方便吗?阿里云 PolarDB-X 100% MySQL 协议兼容零改造平滑迁移
数据库·分布式·mysql