什么是 subprocess.Popen?
subprocess.Popen 是 Python 标准库 subprocess 模块中的一个核心类,
用于创建新进程、连接到它们的输入/输出/错误管道,并获取返回码。
相比于 os.system() 或 os.popen(),Popen 更加灵活、安全且功能强大。
基本用法示例
运行一个简单的命令并获取输出:
import subprocess
# 启动子进程
proc = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# 等待进程结束并读取输出
stdout, stderr = proc.communicate()
print("标准输出:")
print(stdout.decode('utf-8'))
print("标准错误:")
print(stderr.decode('utf-8'))
常用参数说明
args:要执行的命令,可以是字符串(需设置shell=True)或命令列表。stdin/stdout/stderr:分别指定标准输入、输出和错误流,常设为subprocess.PIPE。shell:是否通过系统 shell 执行命令(默认False)。注意:启用时需防范命令注入风险。cwd:设置子进程的工作目录。env:设置子进程的环境变量。
安全提示
使用 shell=True 时,如果命令中包含用户输入,务必进行严格校验或转义,避免 命令注入攻击。
推荐使用命令列表形式(如 ['command', 'arg1', 'arg2'])而非字符串拼接。
不安全示例(避免):
# 危险!不要这样做
user_input = "file.txt; rm -rf /"
subprocess.Popen(f"cat {user_input}", shell=True)
安全做法:
import shlex
filename = "file.txt"
# 若必须用字符串,使用 shlex.split()
cmd = shlex.split(f"cat {filename}")
subprocess.Popen(cmd) # shell=False(默认)
常见应用场景
- 调用系统工具(如
git,ffmpeg,curl) - 执行脚本(Bash、PowerShell 等)
- 与长期运行的子进程交互(如启动服务器、监控日志)
- 并行处理多个外部任务
替代方案建议
对于简单的一次性命令执行,推荐优先使用 subprocess.run()(Python 3.5+),
它更简洁且自动处理等待和异常:
result = subprocess.run(['echo', 'Hello'], capture_output=True, text=True)
print(result.stdout)