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下

相关推荐
JAVA学习通几秒前
微服务项目->在线oj系统(Java-Spring)----[前端]
java·开发语言·前端
瓜瓜怪兽亚2 分钟前
前端基础知识---10 Node.js(三)
数据结构·数据库·node.js
拾贰_C7 分钟前
【SpringBoot】前后端联动实现条件查询操作
java·spring boot·后端
掘根2 小时前
【Qt】常用控件3——显示类控件
开发语言·数据库·qt
码码哈哈爱分享2 小时前
MariaDB 与 MySQL 区别
数据库·mysql·mariadb
爱敲代码的TOM2 小时前
深入MySQL底层1-存储引擎与索引
数据库·mysql
GUIQU.2 小时前
【QT】嵌入式开发:从零开始,让硬件“活”起来的魔法之旅
java·数据库·c++·qt
silent_missile4 小时前
用C#做CATIA二次开发(1)
microsoft
牛奶咖啡136 小时前
关系数据库MySQL的常用基础命令详解实战
数据库·mysql·本地远程连接到mysql·创建mysql用户和密码·修改mysql用户的密码·设置mysql密码的使用期限·设置和移除mysql用户的权限
callJJ6 小时前
从 0 开始理解 Spring 的核心思想 —— IoC 和 DI(2)
java·开发语言·后端·spring·ioc·di