概述
自从转 Go 之后,好久没写 Python 了。最近在 Ubuntu 24.04 中使用 pipx
安装了一个工具之后,运行报依赖错误。把上下文喂给 DeepSeek 之后,最终解决了问题。
我让 DeepSeek 回顾问答的上下文,整理了一篇文章出来——不过相比上一篇,这次我人工介入修改的内容多得多。
问题提出
最近需要扣一个图,把我的证件照背景颜色换一换。搜了一下,在 Github 上找到一个高 star 的项目 rembg 的图片背景去除工具,用 pipx install rembg
安装后运行时,却遇到了 ModuleNotFoundError: No module named 'onnxruntime'
的错误。这明显是包依赖问题。奇怪了,看起来 pipx 没有 pip 那么聪明?
为什么用 pipx 而不是 pip?
在 Ubuntu 24.04 中,系统默认安装了 Python 3.12,所以我就不用费心去自己通过源码安装。但为了避免污染全局环境,官方不推荐使用 pip
,而是 pipx
来管理命令行工具。原因如下:
- 系统 Python 的自我保护: Ubuntu 的系统工具(如
apt
)依赖 Python 环境,直接使用pip
安装全局包可能导致依赖冲突,甚至破坏系统功能。 - 隔离性需求:
pipx
会为每个包创建独立的虚拟环境,避免包之间的依赖冲突。例如,安装rembg
时,其依赖的numpy
版本不会影响其他工具。 - 命令行工具的天然适配:
pipx
会自动将包的可执行文件链接到~/.local/bin
,无需手动配置环境变量,适合管理rembg
这类 CLI 工具。
现象
安装 rembg
看似成功,但运行时直接报错:
$ rembg i input.png output.png
Traceback (most recent call last):
File "/root/.local/bin/rembg", line 5, in <module>
from rembg.cli import main
File "/root/.local/share/pipx/venvs/rembg/lib/python3.12/site-packages/rembg/__init__.py", line 5, in <module>
from .bg import remove
File "/root/.local/share/pipx/venvs/rembg/lib/python3.12/site-packages/rembg/bg.py", line 7, in <module>
import onnxruntime as ort
ModuleNotFoundError: No module named 'onnxruntime'
关键信息: rembg
运行时找不到 onnxruntime
模块。
解决方案
找 DeepSeek 问,说实话,DeepSeek 对问题的原因的解释并不能让我满意,它给出的解决方法也有好几条。经过 7 轮问答,我最终挑选了一个可行的方案。
被验证不可行的方案
- 强制重装
rembg
尝试卸载后强制重装,但问题依旧:
pipx uninstall rembg
pipx install rembg --force
- 全局安装
onnxruntime
直接运行 pipx install onnxruntime
,这个方法可以,但是依赖又不止这一个,一个个安装挺麻烦的。此外 pipx install
会为 onnxruntime
创建新虚拟环境,而非注入到 rembg
的环境,推荐用 pipx inject
的模式。
关键操作: pipx inject
vs pipx install
1. pipx inject
的作用
- 精准注入依赖: 将指定包安装到某个应用的虚拟环境中。
- 解决依赖隔离问题: 例如,为
rembg
单独安装onnxruntime
:
pipx inject rembg onnxruntime
最终解决方案: 自动化脚本
- 自动捕获缺失依赖: 从错误日志中提取
ModuleNotFoundError
提示的模块名。 - 循环安装与重试: 直到命令成功或达到最大重试次数。
#!/bin/bash
# auto_fix_pipx_deps_loop_fixed.sh
# 配置参数
PACKAGE="rembg" # 替换为你的包名
COMMAND="rembg" # 替换为需要执行的命令
MAX_RETRY=20 # 最大重试次数,防止无限循环
# 临时日志文件
LOG="/tmp/pipx_error.log"
# 初始化计数器
retry_count=0
success=0
while [ $retry_count -lt $MAX_RETRY ] && [ $success -eq 0 ]; do
# 清理旧日志
rm -f "$LOG"
# 运行命令并捕获输出,同时记录原始退出状态码
echo "尝试运行命令 (第 $((retry_count+1)) 次)..."
$COMMAND 2>&1 | tee "$LOG"
original_exit_code=${PIPESTATUS[0]} # 获取原命令的退出状态码
# 检查命令是否成功
if [ $original_exit_code -eq 0 ]; then
echo "命令执行成功!"
success=1
break
else
echo "命令执行失败,退出码: $original_exit_code"
fi
# 提取缺失的模块名(去重)
MISSING_MODULES=$(grep -o "ModuleNotFoundError: No module named '[^']*'" "$LOG" | awk -F"'" '{print $2}' | sort | uniq)
if [ ! -z "$MISSING_MODULES" ]; then
echo "检测到缺失依赖: $MISSING_MODULES"
for MODULE in $MISSING_MODULES; do
echo "正在安装: $MODULE"
pipx inject "$PACKAGE" "$MODULE"
if [ $? -ne 0 ]; then
echo "安装依赖 $MODULE 失败,请手动处理。"
exit 1
fi
done
else
echo "未检测到缺失的 Python 依赖。请检查以下可能原因:"
echo "1. 系统级依赖未安装(如 libgomp1)"
echo "2. 动态导入的依赖未在代码中显式声明"
echo "3. 其他运行时错误(查看日志: $LOG)"
break
fi
# 增加重试计数
retry_count=$((retry_count+1))
done
# 最终状态检查
if [ $success -eq 0 ]; then
echo "已达到最大重试次数 ($MAX_RETRY),问题仍未解决。请手动检查日志: $LOG"
exit 1
else
exit 0
fi
脚本运行效果
执行效果类似于这样子的:
尝试运行命令 (第 1 次)...
Traceback (most recent call last):
File "/root/.local/bin/rembg", line 5, in <module>
from rembg.cli import main
ModuleNotFoundError: No module named 'onnxruntime'
检测到缺失依赖: onnxruntime
正在安装: onnxruntime
injected package onnxruntime into venv rembg
尝试运行命令 (第 2 次)...
Traceback (most recent call last):
File "/root/.local/bin/rembg", line 5, in <module>
from rembg.cli import main
File "/root/.local/share/pipx/venvs/rembg/lib/python3.12/site-packages/rembg/cli.py", line 4, in <module>
from .commands import command_functions
File "/root/.local/share/pipx/venvs/rembg/lib/python3.12/site-packages/rembg/commands/__init__.py", line 7, in <module>
from .s_command import s_command
File "/root/.local/share/pipx/venvs/rembg/lib/python3.12/site-packages/rembg/commands/s_command.py", line 6, in <module>
import aiohttp
ModuleNotFoundError: No module named 'aiohttp'
命令执行失败,退出码: 1
检测到缺失依赖: aiohttp
正在安装: aiohttp
injected package aiohttp into venv rembg
......
安装过程中会出现一些失败的情况,一般都是超时等网络问题。解决网络错误之后再跑这个脚本就行了
本文章采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。
原作者: amc,欢迎转载,但请注明出处。
原文标题: 《AI 写文章系列——Ubuntu 24.04 pipx install 解决 ModuleNotFoundError 问题》
发布日期: 2025-03-29
原文链接: https://cloud.tencent.com/developer/article/2508854。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。