Python 执行系统命令的三种方式与 subprocess 详解
在 Python 开发中,调用外部系统命令(如 Linux 的 ls、cp 或 Windows 的 dir)是常见需求。本文总结了三种执行命令的方法,并深入解析了功能最强大的 subprocess 模块,包括其核心类 Popen 的参数配置与进程交互机制。
执行系统命令的三种方法
Python 提供了多种调用外部程序的途径,根据对输出结果和进程控制的需求不同,主要可分为以下三类:
1. 使用 os.system
这是最简单直接的方式,适用于只需要执行命令且不需要获取返回结果或标准输出的场景。该方法会直接打印命令在终端的执行信息。
import os
os.system("ls")2. 使用 commands 模块(仅限 Linux/Unix)
在 Linux 环境下,可以使用内置的 commands 模块。它提供了更高层级的封装,适合快速获取命令的状态码或输出内容。
import commands
# 获取状态码和输出
status, output = commands.getstatusoutput("ls")
# 仅获取输出
commands.getoutput("ls")
# 仅获取状态
commands.getstatus("ls")3. 使用 subprocess 模块(推荐)
subprocess 模块是 Python 官方推荐的用于生成和管理新进程的模块。它提供了更细粒度的控制,允许开发者捕获标准输入、输出和错误流,并处理进程间的通信。使用前需导入:
from subprocess import Popen, PIPEsubprocess.Popen 核心参数解析
Popen 类是 subprocess 模块的核心,用于创建子进程。其构造函数包含大量参数,用于精确控制子进程的行为:
subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)关键参数说明如下:
- args: 要执行的命令或程序路径。
- bufsize: 指定缓冲大小。
- executable: 指定要执行的可执行程序。当
shell=True时,此参数指定使用的 shell。 - shell: 若为 True,则通过 shell 执行命令。Windows 下默认 shell 由 COMSPEC 环境变量指定。
- stdin, stdout, stderr: 可设置为 PIPE、文件描述符或 None。使用
subprocess.PIPE可初始化这些流以进行进程间通信。若将stderr初始化为subprocess.STDOUT,则错误信息将通过标准输出流输出。 - preexec_fn: 仅在 Unix 平台有效,指定在子进程执行前调用的对象。
- close_fds: Windows 下若为 True,则不继承父进程管道。注意:不能将 close_fds 设为 True 同时重定向标准输入、输出或错误流。
- cwd: 用于设置子进程的当前工作目录。
- env: 字典类型,指定子进程的环境变量;若为 None,则继承父进程环境。
- universal_newlines: 若为 True,统一将换行符当作
/n处理。 - startupinfo 与 creationflags: 仅在 Windows 下有效,用于控制进程创建标志。
Popen 对象的方法与属性
创建 Popen 实例后,可通过其属性和方法监控和控制子进程:
常用属性
- pid: 获取子进程的进程 ID。
- returncode: 获取进程返回值。若进程尚未结束,返回 None。
- stdin, stdout, stderr: 返回文件对象,用于发送或读取指令。若未设置为 PIPE,则为 None。
常用方法
- poll(): 检查子进程是否结束,并返回 returncode。
- wait(): 等待子进程结束,并返回 returncode。注意:这是一个阻塞方法,若命令内容较多或产生大量输出,可能导致主程序阻塞。
- communicate(input=None): 与子进程交互,可选 input 指定发送参数。该方法返回一个元组
(stdoutdata, stderrdata),是获取命令输出和错误信息的推荐方式。 - send_signal(signal): 向子进程发送信号。
- terminate(): 停止子进程。在 Windows 下调用 TerminateProcess()。
- kill(): 杀死子进程。
实战示例:执行命令并处理返回值
以下示例展示了如何使用 Popen 执行复制命令,并通过 PIPE 捕获输出和错误,最后检查返回值以判断执行是否成功。
p = Popen("cp -rf a/* b/", shell=True, stdout=PIPE, stderr=PIPE)
p.wait()
if p.returncode != 0:
print "Error."
return -1在此示例中:
- 通过
stdout=PIPE, stderr=PIPE初始化标准输出和错误流,以便后续读取。 - 调用
p.wait()阻塞等待进程结束。 - 检查
p.returncode,非 0 表示执行出错。
注意事项与排错
- 阻塞问题:Popen 默认是阻塞的。如果不使用
wait()或communicate(),虽然避免了阻塞,但无法获取返回值和输出。对于长时间运行的命令,建议使用communicate()以避免死锁。 - 平台差异:部分参数(如
preexec_fn)仅在 Unix 平台有效,Windows 下使用需注意兼容性问题。 - 管道重限制:在 Windows 下,若
close_fds=True,则不能同时重定向标准输入、输出或错误流,否则会导致异常。
以上就是对 Python 中执行系统命令的三种方法及 subprocess 模块详细用法的总结,更多关于 Python 进程管理的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









