前言
昨天凌晨,我又一次被pip搞崩溃了。
事情是这样的:新项目需要Python 3.10,当我敲下pip install -r requirements.txt
,时居然报错: ssl module in Python is not available 。这熟悉的配方让我心头一紧------ 又得开始我的Python版本俄罗斯方块了 。 打开终端看了一下,当场傻眼:
bash
$ which python
/opt/homebrew/bin/python
$ which python3
/Library/Frameworks/Python.framework/Versions/3.11/bin/python3
$ which python3.10
/Users/xxx/.pyenv/versions/3.10.0/bin/python3.10
$ ls -la /usr/local/bin/python* | wc -l
12
那一刻我终于明白,为什么每次被问到"说说Python环境管理",我都想掀桌子。
但是等等!
2小时后,我用200行Bash脚本,不仅把这团乱麻理得清清楚楚,还发现了一个99%的人都不知道的真相: macOS上的Python其实有4种不同的安装方式,每种都有专属的卸载方法 。
现在我的系统只剩下必需的Python(系统Python和我心爱是的conda),清爽得像刚出厂的MacBook。关键是,整个过程没有破坏任何系统依赖,连结构精密的conda环境都毫发无伤。
先别急,在给你脚本之前,我得先说清楚为什么rm -rf
会毁掉你的系统------有3个坑我踩到第2个时才意识到严重性。
别再用rm -rf
了!200行Bash脚本教你安全卸载,连系统Python都保护得好好的
为什么rm -rf会毁掉你的macOS?我踩的3个连环坑
前方高能! 即将开始报错史诗
1.系统Python的死亡连锁
当我愤怒地执行sudo rm -rf /Library/Frameworks/Python.framework/Versions/3.9
后,噩梦开始了:
bash
# 3分钟后,我发现WiFi图标消失了
$ networksetup -listallnetworkservices
-bash: networksetup: command not found
# 原来networksetup是用Python写的!
$ file /usr/sbin/networksetup
/usr/sbin/networksetup: Python script executable (binary data)
2. Homebrew的自杀式依赖
bash
$ brew list
Warning: You are using macOS 13.3.1.
Warning: We do not provide support for this pre-release version.
Error: undefined method `path' for nil:NilClass
$ head -n 1 /opt/homebrew/bin/brew
#!/System/Library/Frameworks/Ruby.framework/Versions/Current/usr/bin/ruby
homebrew依赖错误!!
3. 你真的「只是把Python删了」吗?
bash
# 看似无害的删除
$ rm -rf /usr/local/bin/python3.11
# 结果导致git无法提交
$ git commit -m "fix"
git: error: unable to locate xcode-select
# 因为git的某些钩子脚本依赖Python!
为什么macOS离不开Python?
- 系统级依赖
- WiFi管理、蓝牙配置、系统更新都是Python脚本
- 删除后会出现诡异现象:音量键失灵、触控板手势失效
- 开发工具链
- git、vim、tmux的插件系统
- 甚至 ls 命令的某些增强功能(删完之后你可能连ls都不能正常用了)
这就是为什么我的脚本要做 三重保护 :
- 检测系统Python并跳过
- 识别conda环境并保护
- 交互式确认每个删除操作
99%的人不知道的真相:macOS上的Python其实有4种"血统"
经过血泪教训后,我发现根本问题不是Python太多,而是我们没分清它们的"出身"!就像你不能用拆迁队的办法对付故宫,不同来源的Python需要不同的处理方式。
第1种:系统原生Python(皇家血统)
bash
# 它们住在紫禁城里
/System/Library/Frameworks/Python.framework/
/usr/bin/python2.7
/usr/bin/python3
特征 :macOS自带,删除=系统崩溃 识别技巧 :路径带System/Library
,文件权限是root:wheel
第2种:Homebrew Python(平民血统)
bash
# Homebrew的正规军
/opt/homebrew/Cellar/python@3.11/
/opt/homebrew/bin/python3 -> ../Cellar/python@3.11/3.11.4/bin/python3
特征 :brew安装,符号链接多 识别技巧 :brew list | grep python
能查到
第3种:官方安装包Python(移民血统)
bash
# Python.org的正规移民
/Library/Frameworks/Python.framework/Versions/3.11/
/Applications/Python 3.11/
特征 :有独立的Applications目录 识别技巧 :ls /Library/Frameworks/Python.framework/Versions/
能看到版本号
第4种:pyenv Python(流浪血统)
bash
# pyenv管理的临时居民
~/.pyenv/versions/3.10.0/
~/.pyenv/versions/miniconda3-latest/
特征 :在用户目录下,版本可切换 识别技巧 :pyenv versions
能列出所有
实战:如何一眼识别"谁是谁"?
我写了这个检测函数:
bash
idPythonSource() {
local python_path=$1
case "$python_path" in
/System/Library/*)
echo "❌ 系统Python - 禁止删除"
;;
/opt/homebrew/*)
echo "🍺 Homebrew Python - 可用brew卸载"
;;
/Library/Frameworks/Python.framework/*)
echo "📦 官方安装包 - 可安全删除"
;;
~/.pyenv/*)
echo "🔧 pyenv Python - 可用pyenv卸载"
;;
esac
}
下集预告
下一段预告:当你搞清这4种血统后,真正的挑战才开始------如何在不触发系统级依赖的情况下,精准删除特定版本?我踩的第4个坑,连StackOverflow都没人提过... 【未完待续】
现在你已经学会了识别4种Python的"血统",但真正的挑战才刚刚开始:
- 如何在不触发系统依赖的情况下精准删除?
- 那个连StackOverflow都没人提过的第5种安装方式是什么?
- 我的脚本是如何在删除后自动修复PATH的?
下一篇《精准删除:200行Bash脚本如何避开所有系统依赖?》将揭晓答案...
评论区说说:你遇到过最离谱的Python版本问题是什么?