在Python中执行DOS命令(在Windows系统中)或Shell命令(在Linux/macOS系统中)是一项常见的需求,特别是在需要与操作系统交互、自动化系统任务或调用外部工具时,Python提供了多种方式来实现这一功能,其中最常用的是subprocess模块,它功能强大且灵活,能够满足大多数场景的需求。os.system和os.popen等也可以用于执行命令,但subprocess模块在控制进程输入输出、错误处理和超时管理等方面更具优势。

使用subprocess模块执行命令
subprocess模块是Python推荐用于创建和管理子进程的工具,通过subprocess.run()、subprocess.Popen()等函数,可以轻松执行命令并获取结果,以下是一些常见的用法示例:
基本命令执行
使用subprocess.run()可以执行简单命令并获取返回结果,执行dir命令(Windows)或ls命令(Linux/macOS):
import subprocess # Windows系统 result = subprocess.run(['dir'], shell=True, capture_output=True, text=True) print(result.stdout) # Linux/macOS系统 result = subprocess.run(['ls', '-l'], shell=False, capture_output=True, text=True) print(result.stdout)
shell=True:允许命令通过系统Shell执行,可以直接使用字符串形式的命令(如'dir'),但需注意安全性问题,避免命令注入。capture_output=True:捕获标准输出和标准错误。text=True:以文本形式返回输出,默认为字节形式。
处理命令参数
如果命令需要动态参数,建议使用列表形式传递参数,避免Shell注入风险。
import subprocess file_path = "example.txt" command = ['type', file_path] # Windows中的type命令 result = subprocess.run(command, shell=False, capture_output=True, text=True) print(result.stdout)
获取命令返回码
命令执行后,可以通过returncode属性检查是否成功(0表示成功):

result = subprocess.run(['nonexistent_command'], shell=True, capture_output=True)
if result.returncode != 0:
print(f"命令执行失败: {result.stderr}")
超时处理
使用timeout参数可以设置命令执行的超时时间,避免长时间阻塞:
try:
result = subprocess.run(['ping', 'google.com'], shell=False, timeout=5, capture_output=True, text=True)
print(result.stdout)
except subprocess.TimeoutExpired:
print("命令执行超时")
交互式命令执行
对于需要交互的命令(如输入密码),可以使用subprocess.Popen和communicate()方法:
import subprocess process = subprocess.Popen(['ftp', 'example.com'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) stdout, stderr = process.communicate(input='username\npassword\n') print(stdout)
其他方法对比
除了subprocess,Python还提供了其他执行命令的方式,但功能有限:
-
os.system
简单直接,但无法直接获取命令输出,仅能通过返回码判断是否成功:
(图片来源网络,侵删)import os return_code = os.system('dir') -
os.popen
可以获取命令输出,但已被subprocess取代,不推荐使用:import os output = os.popen('dir').read()
不同操作系统的注意事项
- Windows:DOS命令通常通过
cmd.exe执行,需设置shell=True或使用['cmd', '/c', 'command']。 - Linux/macOS:Shell命令(如
bash)可直接执行,建议使用列表形式避免Shell注入。
命令执行中的常见问题
- 编码问题:不同系统默认编码可能不同,建议在
subprocess.run()中指定encoding和errors参数。 - 路径问题:命令中的路径需使用绝对路径或确保当前工作目录正确。
相关命令执行场景总结
| 场景 | 推荐方法 | 示例代码片段 |
|---|---|---|
| 简单命令执行 | subprocess.run |
subprocess.run(['ls']) |
| 需要捕获输出 | subprocess.run(capture_output=True) |
result = subprocess.run(['dir'], capture_output=True) |
| 超时控制 | subprocess.run(timeout=5) |
subprocess.run(['ping', 'google.com'], timeout=5) |
| 交互式命令 | subprocess.Popen |
process = subprocess.Popen(['ftp'], stdin=PIPE) |
相关问答FAQs
Q1: 如何在Python中执行DOS命令并实时获取输出?
A: 使用subprocess.Popen结合poll()或communicate()可以实现实时获取输出。
import subprocess
process = subprocess.Popen(['ping', 'google.com'], stdout=subprocess.PIPE, text=True)
while True:
output = process.stdout.readline()
if output == '' and process.poll() is not None:
break
if output:
print(output.strip())
Q2: 为什么使用subprocess.run时建议避免shell=True?
A: shell=True可能引发安全风险(如命令注入攻击),且在不同Shell中行为可能不一致,推荐使用列表形式传递命令参数,例如['ls', '-l']而非'ls -l'。
