Python subprocess 模块
Python3 学习笔记 · 整理自菜鸟教程
一句话
subprocess 用来在 Python 里启动并管理外部命令/子进程,能拿到退出码、标准输出和标准错误。
要点
- 首选
subprocess.run():一个调用完成“启动→等待→收集结果”。 - 返回
CompletedProcess对象,含returncode、stdout、stderr。 capture_output=True捕获输出;text=True让输出是str而非bytes。check=True:退出码非 0 时自动抛CalledProcessError。timeout=:超时抛TimeoutExpired,避免卡死。Popen是更底层接口,适合需要边跑边读、后台运行、管道的场景。shell=True时命令是字符串,交给系统 shell 解析;有命令注入风险,能用列表就别开 shell。- 传参数的推荐形式是列表:
['ls', '-l', '/tmp'],避免手动转义空格。 cwd=指定工作目录,env=指定环境变量,input=传标准输入。- 旧接口
call/check_call/check_output仍可用,但新代码优先run。
语法 / 常用方法
| 语法/方法 | 说明 | 示例 |
|---|---|---|
subprocess.run(cmd) |
运行并等待,返回结果对象 | run(['ls', '-l']) |
capture_output=True |
捕获 stdout/stderr | run(cmd, capture_output=True) |
text=True |
以文本模式处理输出 | run(cmd, text=True) |
check=True |
非 0 退出码抛异常 | run(cmd, check=True) |
timeout=秒 |
超时限制 | run(cmd, timeout=5) |
cwd=路径 |
工作目录 | run(cmd, cwd='/tmp') |
env=字典 |
自定义环境变量 | run(cmd, env={...}) |
input='...' |
传给子进程的标准输入 | run(cmd, input='data', text=True) |
result.returncode |
退出码,0 为成功 | if r.returncode == 0 |
result.stdout |
标准输出 | r.stdout.strip() |
result.stderr |
标准错误 | r.stderr |
subprocess.Popen(...) |
底层启动进程 | p = Popen(cmd) |
p.communicate() |
交互/等待并取输出 | out, err = p.communicate() |
p.wait() |
等待结束,返回退出码 | p.wait() |
subprocess.check_output(cmd) |
运行并返回 stdout | 非 0 抛异常 |
subprocess.CalledProcessError |
check 失败时的异常 | 含 returncode |
代码示例
1 | |
易错点
shell=True拼用户输入 = 命令注入漏洞;能用参数列表就别开 shell,非要开的先严格校验。- 输出默认是
bytes,忘了text=True会看到b'...',字符串方法也对不上。 - 不捕获输出时
stdout是None,直接.strip()会报AttributeError。 - 子进程写满管道缓冲区而父进程没读,会死锁,用
run或communicate一次读完。 check=True失败抛异常而不是返回错误码,别再用返回值判断,用try/except。- 参数别手动拼成带引号的字符串,直接传列表,让 Python 处理空格和特殊字符。