本文详细介绍 Python3 subprocess 模块 全套知识,包括模块作用、核心函数、参数详解、进程控制、输出捕获、错误处理、超时设置、管道通信、安全规范与 20 + 可直接运行实战案例。所有示例均在代码中以注释形式标注预期输出,无需运行即可直观查看,适合零基础小白、运维、后端开发者快速掌握,建议收藏反复阅读。
前言
在 Python 开发中,执行系统命令、调用外部程序、处理进程输入输出、编写自动化运维脚本是极为常见的需求。传统的os.system()、os.popen()等方法功能单一、输出难以捕获、安全性较低,而subprocess作为 Python 官方推荐的标准库,完美替代了老旧模块,提供统一、强大、安全的进程创建与管理能力,支持 Windows/Linux/macOS 跨平台使用。
本专栏带你从零基础入门,系统掌握 subprocess 的所有用法,从最简单的命令执行,到复杂的管道通信、异步输出、进程管控,全部用清晰案例讲解。无论你是编程新手、自动化爱好者、运维工程师,还是后端开发人员,都能快速上手,写出稳定高效的进程管理代码。
🌐 前篇文章咱们讲解了 Python3 模块学习教程,如果忘记了,可以去重温一下,不停的重复敲击基础代码,有助于让你更加熟练掌握一门语言。今天咱们学习 Python3 subprocess 模块全面实战教程,下面开始吧!
在 Python 与系统交互的场景里,subprocess 是绕不开的核心模块。它可以启动新进程、连接输入 / 输出 / 错误管道、获取返回值,让你用 Python 轻松 “指挥” 操作系统。本文从基础到高级全覆盖讲解,所有代码示例均内置注释式预期输出,方便读者直接阅读学习。
一、什么是 subprocess 模块?
subprocess 是 Python3 内置的进程管理标准库,无需额外安装,直接导入即可使用。核心作用:
- 在 Python 程序中创建和控制子进程
- 执行系统命令、exe/bat/sh 脚本、第三方软件
- 捕获标准输出、标准错误、命令返回码
- 支持管道、超时、参数传递、工作目录指定
- 替代
os.system()、os.popen()、commands等旧接口
一句话总结:subprocess 让 Python 具备操控系统进程、与系统深度交互的能力。
二、subprocess 核心优势
- API 统一易用一套接口覆盖命令执行、流捕获、错误处理,学习成本低。
- 安全性更高支持列表传参,有效避免 Shell 注入风险。
- 控制粒度精细可设置超时、编码、环境变量、重定向流等。
- 信息完整同时获取输出、错误、返回码,便于业务逻辑判断。
- 跨平台兼容一套代码可在 Windows、Linux、macOS 平稳运行。
三、subprocess 核心函数
Python3.5 及以上版本推荐使用优先级:
subprocess.run():官方首选,阻塞执行,功能最全subprocess.Popen():底层高级类,支持异步、实时输出- 辅助函数:
call()、check_call()、check_output()
四、subprocess.run () 用法详解
4.1 语法结构
python
运行
subprocess.run(
args,
stdout=None,
stderr=None,
shell=False,
cwd=None,
timeout=None,
check=False,
text=False,
encoding=None
)
4.2 直接执行命令(不捕获输出)
python
运行
import subprocess
# 执行dir命令列出当前目录文件,直接打印到控制台
subprocess.run(["dir"], shell=True, text=True, encoding="gbk")
# 预期输出(控制台直接打印):
# 驱动器 D 中的卷是 数据
# 目录 D:\source\py
# 2026-04-13 15:00 <DIR> .
# 2026-04-13 15:00 <DIR> ..
# 2026-04-13 14:55 256 app.py
4.3 捕获标准输出 stdout
python
运行
import subprocess
result = subprocess.run(
["ping", "127.0.0.1", "-n", "2"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True,
text=True,
encoding="gbk"
)
print("返回码:", result.returncode)
# 输出:返回码:0
print("输出内容:\n", result.stdout)
# 输出内容:
# 正在 Ping 127.0.0.1 具有 32 字节的数据:
# 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128
# 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128
4.4 捕获标准错误 stderr
python
运行
import subprocess
result = subprocess.run(
["ipconfig", "aaa"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True,
text=True,
encoding="gbk"
)
print("错误输出:\n", result.stderr)
# 错误输出:
# 错误的参数或命令 - 请键入 "ipconfig /?" 查看用法
4.5 合并 stdout 与 stderr
python
运行
import subprocess
result = subprocess.run(
["dir", "test123456"],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
shell=True,
text=True,
encoding="gbk"
)
print(result.stdout)
# 输出:
# 找不到文件
4.6 命令超时处理
python
运行
import subprocess
try:
subprocess.run(["ping", "1.1.1.1", "-n", "10"], timeout=3, shell=True)
except subprocess.TimeoutExpired:
print("命令执行超时!")
# 输出:命令执行超时!
4.7 check=True 失败抛异常
python
运行
import subprocess
try:
subprocess.run(["wrongcmd"], shell=True, check=True)
except subprocess.CalledProcessError:
print("命令执行失败!")
# 输出:命令执行失败!
五、args 参数:列表 vs 字符串(安全重点)
5.1 列表形式(推荐,安全无注入)
python
运行
subprocess.run(["ping", "127.0.0.1", "-n", "2"])
# 正常执行ping命令,无安全风险
5.2 字符串形式(需 shell=True)
python
运行
subprocess.run("ping 127.0.0.1 -n 2", shell=True)
# 执行结果同列表形式
5.3 Shell 注入风险示例
python
运行
# 危险写法(禁止用于用户输入)
user_input = "127.0.0.1 & del /s /q *.*"
subprocess.run(f"ping {user_input}", shell=True)
# 安全写法(列表传参,杜绝注入)
subprocess.run(["ping", user_input, "-n", "1"])
# 输出:仅执行ping,不会执行恶意命令
六、常用便捷函数
6.1 subprocess.call () 获取返回码
python
运行
import subprocess
code = subprocess.call(["dir"], shell=True)
print("返回码:", code)
# 输出:返回码:0
6.2 subprocess.check_call () 失败抛异常
python
运行
import subprocess
try:
subprocess.check_call(["dir", "nodir"], shell=True)
except subprocess.CalledProcessError:
print("执行失败")
# 输出:执行失败
6.3 subprocess.check_output () 直接获取输出
python
运行
import subprocess
out = subprocess.check_output(["ipconfig"], shell=True, encoding="gbk")
print(out[:200])
# 输出前200字符:
# Windows IP 配置
# 以太网适配器 以太网:
# 连接特定的 DNS 后缀 . . . . . . . :
# 本地链接 IPv6 地址. . . . . . . . : fe80::xxxx
# IPv4 地址 . . . . . . . . . . . . : 192.168.1.100
七、Popen 高级用法
7.1 实时读取输出
python
运行
import subprocess
p = subprocess.Popen(
["ping", "127.0.0.1", "-n", "3"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True,
text=True,
encoding="gbk"
)
for line in p.stdout:
print(line.strip())
# 逐行输出:
# 正在 Ping 127.0.0.1 具有 32 字节的数据:
# 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128
# 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128
p.wait()
print("返回码:", p.returncode)
# 输出:返回码:0
7.2 获取 PID 并终止进程
python
运行
import subprocess
p = subprocess.Popen(["notepad.exe"], shell=True)
print("进程PID:", p.pid)
# 输出:进程PID:12340
p.terminate()
print("进程已终止")
# 输出:进程已终止
八、20 个完整实战案例(内置注释输出)
python
运行
import subprocess
# ==========================
# 1. 基础执行 dir 命令
# ==========================
def demo1():
subprocess.run(["dir"], shell=True, text=True, encoding="gbk")
# 输出:当前目录所有文件列表
# ==========================
# 2. 捕获 ping 输出
# ==========================
def demo2():
res = subprocess.run(
["ping", "127.0.0.1", "-n", "2"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True, text=True, encoding="gbk"
)
print(res.returncode) # 0
print(res.stdout)
# 输出 ping 正常回显
# ==========================
# 3. 捕获错误参数输出
# ==========================
def demo3():
res = subprocess.run(
["ipconfig", "aaa"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True, text=True, encoding="gbk"
)
print(res.stderr)
# 输出:错误的参数或命令
# ==========================
# 4. 合并输出与错误流
# ==========================
def demo4():
res = subprocess.run(
["dir", "nonefile"],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
shell=True, text=True, encoding="gbk"
)
print(res.stdout)
# 输出:找不到文件
# ==========================
# 5. 命令超时
# ==========================
def demo5():
try:
subprocess.run(["ping", "1.1.1.1", "-n", "10"], timeout=3, shell=True)
except subprocess.TimeoutExpired:
print("超时") # 输出:超时
# ==========================
# 6. check=True 抛异常
# ==========================
def demo6():
try:
subprocess.run(["wrong"], shell=True, check=True)
except subprocess.CalledProcessError:
print("失败") # 输出:失败
# ==========================
# 7. 获取 ipconfig 信息
# ==========================
def demo7():
res = subprocess.run(
["ipconfig"], stdout=subprocess.PIPE, shell=True, text=True, encoding="gbk"
)
print(res.stdout[:200])
# 输出IP配置信息
# ==========================
# 8. 查看网络端口 netstat
# ==========================
def demo8():
res = subprocess.run(
["netstat", "-ano"], stdout=subprocess.PIPE, shell=True, text=True, encoding="gbk"
)
print(res.stdout[:300])
# 输出网络连接列表
# ==========================
# 9. 安全传参执行 ping
# ==========================
def demo9():
ip = "127.0.0.1"
res = subprocess.run(
["ping", ip, "-n", "1"], stdout=subprocess.PIPE, shell=True, text=True, encoding="gbk"
)
print(res.stdout)
# 输出一次ping结果
# ==========================
# 10. call() 获取返回码
# ==========================
def demo10():
code = subprocess.call(["dir"], shell=True)
print(code) # 0
# ==========================
# 11. check_call() 异常
# ==========================
def demo11():
try:
subprocess.check_call(["dir", "xx"], shell=True)
except:
print("失败") # 失败
# ==========================
# 12. check_output() 输出
# ==========================
def demo12():
out = subprocess.check_output(["ipconfig"], shell=True, encoding="gbk")
print(out[:150])
# 输出IP配置片段
# ==========================
# 13. Popen 实时输出
# ==========================
def demo13():
p = subprocess.Popen(
["ping", "127.0.0.1", "-n", "3"],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
shell=True, text=True, encoding="gbk"
)
for line in p.stdout:
print(line.strip())
# 逐行打印ping结果
p.wait()
print(p.returncode) # 0
# ==========================
# 14. 获取进程 PID
# ==========================
def demo14():
p = subprocess.Popen(["notepad"], shell=True)
print(p.pid) # 输出类似:13579
p.terminate()
# ==========================
# 15. 主动终止进程
# ==========================
def demo15():
p = subprocess.Popen(["ping", "127.0.0.1", "-n", "5"], shell=True)
p.terminate()
print("已杀死") # 已杀死
# ==========================
# 16. 指定工作目录
# ==========================
def demo16():
subprocess.run(["dir"], shell=True, cwd="D:\\")
# 输出 D 盘根目录文件列表
# ==========================
# 17. 管道命令 tasklist|findstr
# ==========================
def demo17():
res = subprocess.run(
"tasklist | findstr python",
stdout=subprocess.PIPE, shell=True, text=True, encoding="gbk"
)
print(res.stdout)
# 输出python进程信息
# ==========================
# 18. 标准输入 stdin
# ==========================
def demo18():
p = subprocess.Popen(
["findstr", "python"],
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
shell=True, text=True
)
out = p.communicate(input="test python\nabc\npython dev")[0]
print(out)
# 输出:
# test python
# python dev
# ==========================
# 19. 判断执行结果
# ==========================
def demo19():
res = subprocess.run(["dir"], shell=True)
print("成功" if res.returncode == 0 else "失败")
# 输出:成功
# ==========================
# 20. 执行 bat 脚本
# ==========================
def demo20():
subprocess.run(["test.bat"], shell=True)
# 输出 test.bat 执行内容
if __name__ == "__main__":
demo1()
九、编码问题说明
- Windows 中文系统:必须使用
encoding="gbk" - Linux / macOS:使用
encoding="utf-8" - 不指定编码会返回 bytes 类型,需手动
decode()
十、Python系统命令执行模块选型对比表
选型说明:表格聚焦各模块核心能力、适配场景,精准区分优劣,助力开发者根据实际需求快速选择合适的模块,避免无效学习和使用风险(标注「适用场景」为核心选型依据)。
| 模块/方法 | 核心能力 | 核心优势 | 核心劣势 | 适用场景 | 选型优先级 | 备注(输出/安全性说明) |
|---|---|---|---|---|---|---|
| os.system() | 执行系统命令,返回退出码 | 语法简单,一行代码即可执行 | 无法捕获stdout/stderr,无超时、无防注入,功能单一 | 临时调试、简单命令执行(无需捕获输出) | 最低(仅临时使用) | 输出直接打印到控制台,无法在代码中复用;无防注入设计,不适合生产环境 |
| os.popen() | 执行命令,可读取标准输出 | 能简单捕获输出,语法较简洁 | 无法捕获stderr、无法获取返回码,无超时,易造成资源泄漏 | 简单场景(仅需读取输出,无需判断执行状态) | 低(不推荐正式使用) | 需手动读取输出流,无法获取错误信息;无防注入设计,安全性一般 |
| commands模块 | 执行命令,可获取输出和返回码(Python2) | Python2中可同时获取输出和返回码 | Python3已废弃,无错误流分离,无超时、无防注入 | 无(仅兼容Python2旧项目,不推荐新增使用) | 无(已废弃) | 仅Python2可用,输出与错误流合并,无法单独捕获stderr |
| subprocess模块 | 执行命令、捕获stdout/stderr、获取返回码,支持超时、异步、管道等高级操作 | 功能全面,安全可控(防注入),API统一,支持跨平台,可精细化控制进程 | 语法较旧模块稍复杂,需熟悉参数配置 | 正式项目、运维脚本、服务端程序、复杂命令执行、需捕获输出/错误的场景 | 最高(强烈推荐) | 可单独/合并捕获输出和错误,返回结构化结果;支持列表传参防注入,适配生产环境 |
选型建议:
-
临时调试、无需捕获输出:可临时使用os.system(),不推荐正式项目使用;
-
正式项目、运维脚本、需要捕获输出/错误、判断执行状态:优先使用subprocess模块;
-
Python3项目:严禁使用commands模块,避免兼容性问题;
-
生产环境:必须使用subprocess模块,杜绝使用os.popen(),降低安全风险和维护成本。
十一、总结
本文系统讲解了 Python3 subprocess 模块的基础用法、核心函数、高级特性、安全规范,并提供 20 个覆盖高频场景的实战案例,所有示例均以注释形式标注预期输出,无需运行即可清晰理解执行结果。
subprocess 是 Python 系统编程、自动化运维、脚本开发的核心模块,掌握它可以轻松实现进程管理、命令调用、日志采集、服务监控等功能。建议结合案例动手练习,逐步熟练使用,后续可结合 psutil、logging 等模块构建完整的自动化工具。
💡下一篇咱们学习 subprocess + psutil 实现进程监控与系统巡检实战!
附录:扩展学习资源
- 官方文档:https://docs.python.org/3/library/subprocess.html
- Python 标准库手册:内置模块用法速查
- 本专栏配套代码:关注博主获取完整可运行工程文件
联系博主
专注 Python 自动化、后端开发、运维实战干货分享,文章通俗易懂、案例可直接运行、零基础友好。
📣 码字不易,欢迎 点赞 + 收藏 + 关注,有问题可留言,看到第一时间回复!

33

被折叠的 条评论
为什么被折叠?



