OpenWrt 集成 Python 的几种方法
主要有三种方法,适用于不同的场景:

-
安装预编译的二进制包(最简单、推荐新手)
- 原理:OpenWrt 的官方软件源 (
opkg) 提供了已经编译好的 Python 解释器和常用库的包。 - 优点:安装简单,快速,依赖关系由
opkg自动处理。 - 缺点:Python 版本可能不是最新的,可用的库包有限。
- 适用场景:快速部署,对 Python 版本和库没有特殊要求。
- 原理:OpenWrt 的官方软件源 (
-
使用
pip安装第三方库(最灵活、最常用)- 原理:在方法一的基础上,使用 Python 的包管理器
pip从 PyPI (Python Package Index) 下载并安装源码,然后在 OpenWrt 上编译。 - 优点:可以安装几乎任何 Python 库,灵活性最高。
- 缺点:编译过程非常耗时(可能需要几十分钟甚至几小时),极度消耗路由器的 CPU 和内存,容易因内存不足而失败。
- 适用场景:需要使用
pip上特定的、OpenWrt 软件源中没有的库(如requests,flask,paho-mqtt等)。
- 原理:在方法一的基础上,使用 Python 的包管理器
-
从源码交叉编译(最专业、用于固件定制)
- 原理:在你的开发主机(如 x86 Linux)上,使用 OpenWrt 的 SDK (Software Development Kit) 将 Python 和你的应用代码一起交叉编译成可以在目标路由器上运行的二进制文件。
- 优点:性能最好,生成的二进制文件是自包含的,不依赖路由器上复杂的编译环境。
- 缺点:设置最复杂,需要熟悉 OpenWrt 的构建系统。
- 适用场景:开发者要制作一个包含自己 Python 应用的定制化 OpenWrt 固件,或者需要为没有足够资源的路由器准备预编译的二进制文件。
详细步骤指南
前提条件
- 已刷入 OpenWrt:你的路由器已经成功安装并运行 OpenWrt。
- 网络连接:路由器能正常上网,以便
opkg下载软件包。 - SSH 访问:建议通过 SSH 连接到路由器,方便操作。
- 可用空间:确保路由器的
/overlay或根分区有足够的剩余空间(至少 50MB 以上,编译pip包需要更多)。
安装预编译的 Python
这是最基础的步骤,无论是哪种方法,你都需要一个 Python 环境。

-
更新软件包列表
opkg update
-
安装 Python OpenWrt 软件源提供了
python3和python3-light。light版本只包含核心库,体积更小,如果不确定需要哪些库,可以先安装light版本,之后按需添加。# 安装 Python 3 核心包 opkg install python3 python3-light # 如果需要更完整的环境(包含 pip 和一些标准库),可以安装 python3-pip opkg install python3-pip
注意:如果你的 OpenWrt 版本较旧,可能没有
python3-pip,或者需要单独安装python3-setuptools和python3-wheel来让pip正常工作。 -
验证安装
(图片来源网络,侵删)python3 --version # 应该输出类似 Python 3.9.x 的版本号 pip3 --version # 如果安装了 python3-pip,这里会显示 pip 的版本
使用 pip 安装第三方库
警告:此过程对路由器性能要求高,如果你的路由器 CPU 性能差(如单核 400MHz)且内存小于 64MB,极有可能失败,建议在性能较好的路由器上操作。
-
安装编译依赖
pip在编译纯 Python 包时通常不需要额外依赖,但如果要编译包含 C/C++ 扩展的包(如numpy,lxml),就需要大量的开发工具链。opkg install python3-dev # 如果编译过程报错缺少头文件,可以尝试安装以下包 # opkg install build-essential # opkg install libssl-dev
-
使用
pip安装库 直接使用pip3命令即可,安装过程会自动下载源码并编译。# 示例:安装 requests 库 pip3 install requests # 示例:安装 Flask,用于创建 Web 服务 pip3 install Flask # 如果编译失败,可以尝试使用 --no-cache-dir 和 --no-binary 选项强制从源码编译 # pip3 install --no-cache-dir --no-binary=:all: some_library
-
管理已安装的库
# 列出所有已安装的包 pip3 list # 卸载一个包 pip3 uninstall Flask
实战示例:创建一个简单的网络状态监控 Web 服务
我们将使用 Flask 框架,在路由器上创建一个网页,显示当前设备的 CPU 使用率、内存使用情况和网络连接数。
-
安装 Flask
pip3 install Flask
-
创建监控脚本 在路由器上创建一个文件,
/etc/network_monitor.py:vi /etc/network_monitor.py
将以下代码粘贴进去:
import subprocess from flask import Flask, render_template_string app = Flask(__name__) HTML_TEMPLATE = """ <!DOCTYPE html> <html> <head> <title>OpenWrt Network Monitor</title> <style> body { font-family: sans-serif; margin: 20px; } h1 { color: #333; } .stat { background-color: #f0f0f0; padding: 10px; margin: 10px 0; border-radius: 5px; } </style> </head> <body> <h1>OpenWrt System Status</h1> <div class="stat"> <h3>CPU Load (1 min, 5 min, 15 min)</h3> <p>{{ cpu_load }}</p> </div> <div class="stat"> <h3>Memory Usage</h3> <p>{{ memory_usage }}</p> </div> <div class="stat"> <h3>Network Connections</h3> <p>{{ connections }}</p> </div> </body> </html> """ def get_cpu_load(): """获取 CPU 负载""" try: output = subprocess.check_output("cat /proc/loadavg", shell=True).decode().strip() return output except Exception as e: return f"Error: {e}" def get_memory_usage(): """获取内存使用情况""" try: output = subprocess.check_output("free -m", shell=True).decode().strip() lines = output.split('\n') # 解析 free 命令的输出,这里简化处理,只取总内存和已用内存 total_line = lines[1] total_mem = int(total_line.split()[1]) used_mem = int(total_line.split()[2]) return f"Total: {total_mem} MB, Used: {used_mem} MB ({used_mem/total_mem*100:.1f}%)" except Exception as e: return f"Error: {e}" def get_connections(): """获取网络连接数""" try: # 使用 netstat -an | grep ESTABLISHED 来统计已建立的连接 # 使用 wc -l 来计算行数 output = subprocess.check_output("netstat -an 2>/dev/null | grep ESTABLISHED | wc -l", shell=True).decode().strip() return f"Established TCP Connections: {output}" except Exception as e: return f"Error: {e}" @app.route('/') def index(): cpu = get_cpu_load() mem = get_memory_usage() conn = get_connections() return render_template_string(HTML_TEMPLATE, cpu_load=cpu, memory_usage=mem, connections=conn) if __name__ == '__main__': # 在生产环境中,应该使用 Gunicorn 或 uWSGI 作为 WSGI 服务器 # 这里为了简单,直接使用 Flask 自带的服务器 # host='0.0.0.0' 允许任何 IP 访问 app.run(host='0.0.0.0', port=5000, debug=True) -
运行脚本
python3 /etc/network_monitor.py
你会看到类似
* Running on http://0.0.0.0:5000/的输出。 -
访问服务 在同一局域网下的另一台电脑(或手机)的浏览器中,输入路由器的 IP 地址和端口号:
http://<你的路由器IP>:5000你就能看到一个显示系统状态的网页了!
-
让脚本在后台持续运行(推荐使用
supervisor) 直接在终端运行python3脚本,一旦关闭 SSH 连接,脚本就会停止,我们可以使用supervisor来管理它。-
安装 supervisor
opkg install supervisor
-
配置 supervisor 创建配置文件
/etc/supervisor/conf.d/network_monitor.conf:vi /etc/supervisor/conf.d/network_monitor.conf
内容如下:
[program:network_monitor] command=python3 /etc/network_monitor.py directory=/etc autostart=true autorestart=true stderr_logfile=/var/log/supervisor/network_monitor_err.log stdout_logfile=/var/log/supervisor/network_monitor_out.log user=root
autostart=true:让 supervisor 在启动时自动运行此程序。autorestart=true:如果程序意外退出,supervisor 会自动重启它。user=root:以 root 用户身份运行,因为脚本需要读取系统文件。
-
启动 supervisor 服务
# 启动 supervisor 主服务 /etc/init.d/supervisor start # 让 supervisor 开机自启 /etc/init.d/supervisor enable
即使你关闭 SSH,你的监控服务也会在后台持续运行。
-
从源码交叉编译(简介)
这个方法比较复杂,不适合普通用户,这里只做概念性介绍。
- 准备环境:在你的 x86 Linux 电脑上下载对应 OpenWrt 版本的 SDK。
- 配置 SDK:进入 SDK 目录,运行
./scripts/feeds update -a和./scripts/feeds install -a。 - 选择软件包:在
package/目录下,你可以看到python3,你可以在这里修改Makefile来指定要编译的 Python 版本或要包含的库。 - 编译:运行
make menuconfig,确保你需要的 Python 和其他软件包被选中,然后执行make V=s开始编译,编译过程会非常长。 - 获取结果:编译成功后,生成的二进制文件和包会在
bin/目录下,你可以将这些文件打包,刷入路由器使用。
总结与建议
| 方法 | 优点 | 缺点 | 推荐场景 |
|---|---|---|---|
| 预编译包 | 简单、快速、稳定 | 库版本旧,可选库少 | 快速部署,基础脚本,资源有限的设备 |
pip 安装 |
库最新最全,灵活性极高 | 编译慢,消耗资源大,易失败 | 需要使用特定 Python 库的开发者和高级用户 |
| 交叉编译 | 性能好,自包含,可定制固件 | 设置复杂,学习曲线陡峭 | 固件开发者,制作分发版 |
对于绝大多数用户来说,“方法一 + 方法二” 是最佳实践,先用 opkg 安装基础 Python,然后用 pip 按需安装库。pip 编译太慢或失败,再考虑使用预编译的库(如果存在)或寻找纯 Python 实现的替代库。
希望这份详细的指南能帮助你在 OpenWrt 上成功集成 Python 并开启你的项目!
