尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

树莓派上指定版本Python的安全卸载指南

树莓派上指定版本Python的安全卸载指南 1. 想明白一件事你手里的Python到底属于谁动手卸载之前我强烈建议你先花五分钟想清楚一个问题你打算卸掉的那个Python版本到底是“谁”的Python。这句话听起来有点绕但我在树莓派上踩过的坑几乎全栽在这上面。树莓派官方的Raspberry Pi OS也就是以前的Raspbian是基于Debian来的整个系统从桌面环境、网络管理器到apt包管理工具全都深度依赖系统自带的Python。换句话说系统自带的那个/usr/bin/python3并不是“给你用”的而是“给系统自己用”的你只是搭了个便车。如果这篇文章你只想记住一句话那就是系统自带的Python版本千万别直接删删了等于拆房子承重墙。那么问题来了标题里说的“指定版本”到底是谁装的正常人会遇到的场景无非下面这几种直接用apt install python3.x装的新版本这种属于“包管理器来源”卸载相对干净但要小心依赖关系。从python.org下载源码然后./configure make install编译安装的版本这种最坑大概率是手动编译进了/usr/local卸载的时候没有包管理器帮你擦屁股。用pyenv或virtualenv管理出来的独立环境这种其实不叫“卸载”叫“删除目录”最安全。还有一种是某个项目或某个框架自己捆绑的Python比如某些嵌入式开发套件、ROS、Kodi插件之类这种你删了它项目就废了得特别谨慎。所以整个卸载动作的闭环其实是先识别来源再选对手段。来源判断错了后面做得越彻底系统越惨。那怎么快速判断呢which python3.11 python3.11 -c import sys; print(sys.executable) apt list --installed | grep python3第二条命令比较关键sys.executable会直接打印出这个Python解释器所在的具体路径。如果路径是/usr/bin/python3.11那就是系统包管理器安装的如果是/usr/local/bin/python3.11那就是源码编译安装的如果在某个用户目录下面比如/home/pi/.pyenv/shims/python3.11那就不用多想了这已经是你自己管的环境了。路径不会骗人先看清路径再动手。2. 三种来源的卸载手段操作手法完全不同2.1 apt安装的Python用包管理器反着来如果确定是apt装的那么卸载的命令非常直白sudo apt remove python3.11但这里有个细节很多人不知道remove和purge不一样。remove只删程序文件配置文件和缓存会留在系统里可能占据很小的磁盘空间但如果这个包有配置文件残留后来又重装回来配置还是旧的可能会造成行为异常。purge则连配置文件一起干掉sudo apt purge python3.11一般我倾向于用purge因为既然是卸载干脆就卸干净。但是这里的“但是”很重要。有些系统依赖这个包比如某些桌面组件或工具链直接卸载会影响系统稳定性。如果你用了remove之后系统提示会卸载一堆别的包一定要看清楚列表里有没有关键系统组件比如python3-apt、python3-minimal、lsb-release这种。这些是底层依赖被捎带着卸了的话你的apt理论上还能用但凡是需要Python支持的组件都会开始报错。补充一个我当时用的稳妥做法sudo apt remove --dry-run python3.11--dry-run参数是模拟运行不打真的。它会列出“如果执行卸载会被影响的所有包”相当于动词的“过一遍脑子再说话”。看到模拟结果里面的动静太大就收手别硬来。如果模拟结果只有几个无关紧要的包再真正执行。2.2 源码编译安装的Python没有后悔药只能手动清源码编译安装的Python最难搞因为系统里没有记录任何包管理器都感知不到它的存在。你当初怎么装的现在就得反着怎么删。先回忆一下或者重新看一遍你的安装方式wget https://www.python.org/ftp/python/3.11.8/Python-3.11.8.tgz tar -zxvf Python-3.11.8.tgz cd Python-3.11.8 ./configure --enable-optimizations make -j4 sudo make install如果当时的安装路径用的是默认值不指定--prefix那它默认被装进/usr/local/bin和/usr/local/lib。这意味着它和系统自带的Python混在一起你手动清理的时候特别容易误伤。make uninstall理论上可以把编译安装的软件卸载掉但Python的Makefile有个老毛病就是uninstall目标不完整的情况很常见经常删不干净。所以我一般建议手动清理步骤如下先删可执行文件sudo rm -f /usr/local/bin/python3.11 sudo rm -f /usr/local/bin/python3.11-config再删库文件sudo rm -rf /usr/local/lib/python3.11最后清理编译缓存目录sudo rm -rf /usr/local/include/python3.11如果你当时用了--prefix/opt/python3.11这种安装路径那就更简单了直接sudo rm -rf /opt/python3.11这种是自定义安装目录所有文件都在一个文件夹里卸载最干净、最省心也最不容易误伤别的文件。编译安装的Python还有一个隐蔽残留地就是/usr/local/bin下的软链接python3。很多时候我们执行的python3指令实际上是指向python3.11的软链接删了主程序软链接还躺在那里变成“死链”。顺手清理掉sudo rm -f /usr/local/bin/python3但要小心别把系统自带的/usr/bin/python3删了这两个路径差了十万八千里。清的时候看清楚路径。2.3 pyenv和venv里的Python压根不算系统软件如果在pyenv里面想删除一个Python版本命令非常简单pyenv uninstall 3.11.8这个命令会把pyenv自己编译好的那个Python整个目录删掉干净利落不影响系统任何东西。如果你是用venv创建的虚拟环境不用什么特殊命令直接删目录就行rm -rf /path/to/myenv因为这些Python环境本质上就是一个隔离的目录树里面所有依赖、解释器、库文件都是复制或链接进来的删除目录即卸载完成。需要留意的是删除虚拟环境之前先想清楚这个环境有没有被IDE、服务脚本或计划任务引用。我之前就干过这种事删了一个venv结果忘了某个cron任务还在调用它半夜定时备份直接崩溃。3. 卸载之后必须处理的残余战场3.1 PATH和软链接的烂摊子卸载完Python版本最典型的症状就是你敲python3.11发现提示找不到命令但敲python3却还是打开了那个升级过的看起来“一切都还在”的假象。这通常是因为PATH路径里还有旧的软链接或者系统环境的默认版本概念已经被工具缓存了。这时候需要检查which python3 ls -la /usr/bin/python3* ls -la /usr/local/bin/python3*如果发现某个python3是指向已删版本的软链接手动修正sudo ln -sf /usr/bin/python3.9 /usr/bin/python3但别太依赖这种“修正”更好的办法是明确自己的实际需求我这个系统到底要用哪个Python版本作为默认想清楚之后把所有软链接统一点到目标版本才不会再出幺蛾子。3.2 pip残余包和用户级site-packages/python版本卸载后那个版本下通过pip安装的一堆第三方库通常还残留在系统里。如果那个版本是系统Python它的site-packages可能和别的版本共享路径直接pip uninstall又怕影响其他版本。最好的做法是先确认当前pip指向哪里which pip3 pip3 --version用你想要的Python版本重新安装或升级pippython3.9 -m ensurepip --upgrade然后重新安装项目依赖。如果你有requirements.txt那就更简单了pip3 install -r requirements.txt这里我多说一句。很多人会忽略~/.local/lib/python3.x/site-packages这个目录它是用户级pip安装的默认位置。如果你曾经用pip install --user装过包旧的Python版本删除后这个目录也会变成垃圾箱。清理的时候一并处理rm -rf ~/.local/lib/python3.113.3 各种环境和工具的残留引用Docker容器里如果用了这个Python版本作为基础镜像那不是说卸载了宿主机的Python容器就自己好了得重新构建镜像。虚拟环境引用、IDE里的解释器路径配置、系统的systemd服务文件里的ExecStart指向这些都是需要手动逐项检查的。我自己的习惯是卸载完一个大版本之后全局搜索一下这个版本的字符串grep -r python3.11 /etc/systemd/system/ 2/dev/null grep -r python3.11 ~/.config/ 2/dev/null把所有引用旧版本的配置都改掉。这步不做下次某个服务重启时你会看到一堆“No such file or directory”到时候排查起来反而多花半小时。4. 我遇到的坎和你们可能遇到的坎4.1 卸载之后桌面环境直接崩了第一次在树莓派上卸载Python时我贪方便用了sudo apt purge python3注意我写的是python3不是python3.11。那一条命令下去整个桌面环境当场报废重启之后直接黑屏只剩命令行登录界面。因为Raspberry Pi OS的桌面是基于Python脚本启动和管理的删掉核心Python等于把桌面的地基也给挖了。事后花了两个小时把系统恢复到可用状态。过程不复杂但很烦重新安装python3、python3-gi、python3-gi-cairo等一大堆包再安装lightdm重启总算恢复。核心教训永远不要在生产或主力环境里直接卸载python3这个包哪怕你觉得它版本旧、占空间、碍眼。如果你觉得占空间请检查是不是pip缓存或pycache占的而不是Python解释器本身。4.2 卸载后apt直接开始报错这是卸载另一个Python版本后最常见的摔倒姿势。具体症状是执行任何apt install命令时都会报错提示某个Python模块缺失装什么包都失败。这背后的原理是apt本身依赖Python的一些库来执行部分脚本逻辑比如update-grub之类的钩子脚本。你卸载了那个Python版本这些脚本就找不到解释器了。我当时排查的过程比较笨但有效sudo apt install -f这个命令是修复依赖关系的。如果报错信息里明确指向某个具体路径比如/usr/bin/python3.11: No such file or directory那就是脚本里写死了旧版本的路径。可以手动改脚本也可以重新安装那个Python版本再正常卸载两种方式我都试过后一种更稳。后来我学乖了卸载前先备份sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak sudo cp /etc/apt/sources.list.d/ /etc/apt/sources.list.d_bak/ -r这不是说卸载Python得有这个备份而是说——动手之前多留一条退路永远不亏。4.3 pip指向了“幽灵解释器”还有一种比较隐蔽的情况卸载了Python 3.11后再执行pip --version发现pip显示的是它对应的路径已经不存在了某个软链接指向了一个已经删除的解释器。出现这个“幽灵pip”的原因很简单pip本身是通过shebang指定了解释器路径的你卸载了解释器pip却还在它只能报错。处理方法python3 -m pip install --upgrade pip用当前可用的Python重新引导pip到自己身上。或者更彻底一点把旧的pip可执行文件删掉which pip3.11 rm -f $(which pip3.11)因为pip只是一个小工具重新安装很容易不用心疼。4.4 删了编译缓存磁盘空间没有明显变化有人卸载完还觉得磁盘没变大就以为自己“没删干净”。其实Linux的磁盘空间占用大头很多时候不是Python解释器本身而是site-packages里装的包、__pycache__缓存、以及~/.cache/pip里的下载缓存。Python解释器真正占用的空间通常不到100MB。所以说如果目标是想腾空间更有效果的是sudo rm -rf ~/.cache/pip find / -type d -name __pycache__ -exec rm -rf {} 2/dev/null这两条命令清掉的是pip缓存和Python缓存往往能释放好几个GB。比单纯删Python版本实在多了。5. 树莓派交叉场景的特殊处理在热词里我又看到“树莓派4交叉编译qt”“树莓派5上部署自己训练的yolov5模型”这类的关键词这类场景刚好涉及到另一个容易踩的坑。如果你在树莓派上交叉编译Qt或者部署深度学习模型比如YOLOv5树莓派板子上往往需要配置一套“干净的Python环境”。这时候常见做法是在开发机上用交叉编译器链去编译Python依赖库然后同步到板子上。但这样操作之后板子上那个“指定版本的Python”来源非常尴尬它既不是apt装的也不是源码装的而是你直接拷贝过去的。这种情况下卸载版本最忌讳用apt因为包管理器压根不知道它的存在。最安全的做法是直接在板子上保留完整目录备份然后用sudo mv /usr/local/python3.11 /usr/local/python3.11_bak先把它挪走而不是删掉。确认系统一切正常后再把备份目录删除。这叫“软卸载”尤其适合在用完交叉编译链之后、准备部署新环境过渡的阶段。另外如果你部署YOLOv5用的ONNX Runtime或者PyTorch它很可能链接的是某个特定Python版本的C扩展。你在系统层面换了默认Python版本可能不会导致原来的Python彻底消失但会导致那些已经编译好的.so文件无法加载。这个时候最稳妥的方案不是“卸载”而是用conda/pyenv建一个独立环境把项目锁在自己的环境里别去动系统级Python。这一点我真是每次回顾都要拿出来提醒一次。6. 一个留下伏笔的小建议用脚本记录自己的操作最后说个我自己的习惯。每次在树莓派上动“删除”级别的大操作我都会把敲过的命令先用history导出留底history ~/operation_log_$(date %Y%m%d).txt这样做的原因很简单如果卸载之后的第三天系统出了新问题我能翻回来看看自己到底做了什么。而且这条日志本身也是复盘的数据来源下次再遇到类似情况就知道直接该走那条路、不该碰哪个包。说回卸载Python这回事它本身不复杂复杂的是你对这个系统里Python生态依赖边界的理解。把来源识别清楚把依赖边界画明白卸载就是几分钟的事。识别不清卸载就成了拆盲盒过程很刺激结果不好说。我在树莓派上反复折腾Python版本最基本的体会是这个系统对Python的依赖比你想象中深得多所以每次卸载都要带着“这是一次外科手术”的心态来做。准备好备份、确认好来源、想好退路再动刀。各种实测下来留好退路永远比卸载速度重要。
返回列表