Python 调用终端命令的 5 种姿势,轻松搞定系统交互!

引言

在 Python 开发中,调用系统终端执行命令是一项常见的需求。无论是文件操作、网络请求,还是与其他工具集成,都需要通过 Python 执行外部命令。然而,Python 提供了多种实现方式,每种方法都有其特点和适用场景。

本文将详细介绍当前最常用的 5 种方法,并结合实际代码示例,帮助您快速掌握这些技术,从而在不同场景下选择最适合的解决方案。


方法一:subprocess.run —— 推荐的标准方法

subprocess.run 是 Python 3.5 引入的一个强大工具,用于执行外部命令并捕获输出。它已经成为官方推荐的标准方法,功能全面且易于使用。

示例代码
import subprocess

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

# 输出结果
print("标准输出:", result.stdout)
print("标准错误:", result.stderr)
print("返回码:", result.returncode)
特点
  • 优点
    • 功能强大,支持捕获标准输出、标准错误以及返回码。
    • 参数设计清晰,避免了字符串拼接带来的安全问题。
  • 缺点
    • 需要手动处理命令参数列表。
  • 适用场景
    • 需要捕获命令输出或错误信息的任务。

方法二:os.system —— 简单但有限

os.system 是最简单的方式之一,适合执行不需要捕获输出的命令。

示例代码
import os

# 执行命令
return_code = os.system("ls -l")  # Linux/macOS
# return_code = os.system("dir")   # Windows

# 输出返回码
print("返回码:", return_code)
特点
  • 优点
    • 使用简单,无需额外模块。
  • 缺点
    • 无法直接获取命令的输出结果。
    • 返回值仅为命令的退出状态码(0 表示成功,非 0 表示失败)。
  • 适用场景
    • 只需执行命令而不需要处理输出的简单任务。

方法三:subprocess.Popen —— 高级控制工具

subprocess.Popen 提供了对子进程的细粒度控制,适合需要实时监控输出或与子进程交互的复杂任务。

示例代码
import subprocess

# 启动子进程
process = subprocess.Popen(["ping", "-c", "4", "www.google.com"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)

# 实时读取输出
for line in process.stdout:
    print("实时输出:", line.strip())

# 获取最终结果
stdout, stderr = process.communicate()
print("标准错误:", stderr)
print("返回码:", process.returncode)
特点
  • 优点
    • 支持实时读取输出,适合长时间运行的命令。
    • 提供了高级控制能力,例如管道通信。
  • 缺点
    • 使用复杂,代码量较大。
  • 适用场景
    • 需要实时监控子进程输出或与子进程交互的复杂任务。

方法四:subprocess.check_output —— 快速获取输出

subprocess.check_output 是一个专注于捕获命令输出的方法,适合只需获取输出的场景。

示例代码
import subprocess

# 执行命令并捕获输出
try:
    output = subprocess.check_output(["ls", "-l"], text=True)
    print("标准输出:", output)
except subprocess.CalledProcessError as e:
    print("命令失败:", e)
特点
  • 优点
    • 直接返回命令的输出结果,使用简单。
  • 缺点
    • 如果命令失败(返回非零状态码),会抛出 subprocess.CalledProcessError 异常。
  • 适用场景
    • 需要快速捕获命令输出的任务。

方法五:asyncio.create_subprocess_shell —— 异步执行命令

在异步编程中,可以使用 asyncio.create_subprocess_shell 来执行外部命令,适合需要与其他异步任务协作的场景。

示例代码
import asyncio

async def run_command():
    # 创建子进程
    process = await asyncio.create_subprocess_shell(
        "ping -c 4 www.google.com",
        stdout=asyncio.subprocess.PIPE,
        stderr=asyncio.subprocess.PIPE
    )

    # 实时读取输出
    async for line in process.stdout:
        print("实时输出:", line.decode().strip())

    # 获取最终结果
    stdout, stderr = await process.communicate()
    print("标准错误:", stderr.decode())
    print("返回码:", process.returncode)

# 运行异步任务
asyncio.run(run_command())
特点
  • 优点
    • 支持异步操作,适合与其他异步任务协同工作。
    • 可以实时监控子进程输出。
  • 缺点
    • 需要熟悉 asyncio 编程模型。
  • 适用场景
    • 异步环境中执行外部命令的任务。

总结

方法优点缺点适用场景
subprocess.run功能强大,捕获输出和错误需要手动处理命令参数需要捕获输出或错误的任务
os.system简单易用无法捕获输出不需要输出的简单任务
subprocess.Popen高级控制,支持实时监控使用复杂复杂任务或实时监控
subprocess.check_output快速捕获输出命令失败会抛异常只需捕获输出的任务
asyncio.create_subprocess_shell支持异步操作需要熟悉 asyncio异步环境中执行命令

希望本文能帮助您更好地理解和掌握这 5 种常用方法!如果您有其他实现方式或疑问,欢迎在评论区分享!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值