Mac 上怎么卸载 Python 和 Node.js
在 Mac 上卸载 Python 或 Node.js,先要弄清楚卸的是哪一份,因为一台 Mac 上通常不止一份,而且每一份的卸法都不一样。用 which -a python3 或 which -a node 看看 PATH 里有几份,再按当初装它的工具来卸,Homebrew 用 brew uninstall,pyenv 用 pyenv uninstall,nvm 用 nvm uninstall,conda 按 Anaconda 官方步骤,python.org 和 nodejs.org 的安装包就删掉它们写进去的文件。/usr/bin/python3 别动,它属于 macOS 和 Apple 的开发者工具。
卸完以后,还要把这些工具往 shell 启动文件里加的那几行删掉,再处理它们留在个人文件夹里的缓存。下面就按这个顺序走,先认出来,再卸载,然后清 PATH、清缓存,最后验证。
找出 PATH 里所有的 Python 和 Node
下面几条命令都是只读的:
which -a python3 python node npm
type -a python3 node
python3 -c 'import sys; print(sys.executable)'
which -a 按 PATH 顺序列出所有匹配,第一行就是你敲命令时真正运行的那个。type -a 还会显示别名和 shell 函数,这对版本管理器很重要,比如 nvm 就把 nvm 定义成一个 shell 函数,pyenv 和一些配置会在真正的程序前面放一层 shim。遇到符号链接,用 ls -l 看它实际指向哪里。
拿路径对照下面这张表:
| 路径开头 | 谁装的 | 怎么卸 |
|---|---|---|
/usr/bin/python3 |
macOS,给 Xcode 和命令行工具用的 | 别动 |
/Library/Frameworks/Python.framework,或 /usr/local/bin 里指向它的链接 |
python.org 安装包 | 删掉它的三部分(见下文) |
/opt/homebrew(Apple 芯片),或 /usr/local/Cellar、/usr/local/opt(Intel) |
Homebrew | brew uninstall |
~/.pyenv/shims 或 ~/.pyenv/versions |
pyenv | pyenv uninstall |
~/anaconda3、~/miniconda3、/opt/anaconda3、/opt/miniconda3 |
Anaconda 或 Miniconda | 先 conda init --reverse,再删文件夹 |
不是 Homebrew 链接的 /usr/local/bin/node |
nodejs.org 安装包 | 删掉它的文件,再忘掉安装收据 |
~/.nvm/versions/node |
nvm | nvm uninstall |
~/Library/Application Support/fnm 或 ~/.fnm |
fnm | 先 fnm uninstall,再删文件夹 |
~/.volta |
Volta | 删掉 ~/.volta |
Intel Mac 上 Homebrew 和 nodejs.org、python.org 的安装包都往 /usr/local 里写东西,所以动那里的文件之前,先用 ls -l 看它是不是指向 Homebrew Cellar 的链接,别想当然地以为是自己装的。
不要删 macOS 自带的 Python
Python 官方的 macOS 文档写得很明白,新版 macOS 里 /usr/bin/python3 这个命令链接的是 Apple 开发工具(Xcode 或 Xcode 命令行工具)自用的 Python,由 Apple 控制,Apple 自己和第三方软件都在用,任何时候都不要修改或尝试删除它,何况它本来就在只读的系统宗卷上。从 python.org 或 Homebrew 再装一份可以和它共存,想换成哪一份运行,改 PATH 就行,不用删 Apple 的那份。
卸载 python.org 安装的 Python
按同一份文档,python.org 的安装包会在 Mac 上放三样东西,一个在「应用程序」里、装着 IDLE 和 Python Launcher 的 Python 3.x 文件夹,一个在 /Library/Frameworks/Python.framework 的框架,以及 /usr/local/bin 里指向可执行文件的符号链接,文档说卸载时删掉这三样即可。
一次卸一个版本,以 3.12 为例:
ls /Library/Frameworks/Python.framework/Versions
ls -l /usr/local/bin | grep 'Python.framework/Versions/3.12'
第一条列出装了哪些版本,第二条显示 /usr/local/bin 里哪些链接指向要卸的这个版本。然后把 /Applications/Python 3.12 移到废纸篓,用管理员权限删掉 /Library/Frameworks/Python.framework/Versions/3.12,再只删第二条命令列出来的那些链接,最后一个版本也卸掉的话,整个 Python.framework 文件夹就可以删了。
安装包还会留下一份收据,用 pkgutil --pkgs | grep -i python 能找到,收据本身不会运行,但 pkgutil --files <id> 能准确列出这个安装包写过哪些文件,比凭记忆找路径可靠得多,怎么读收据、怎么忘掉收据见卸载 .pkg 安装的软件。
卸载 Homebrew 安装的 Python
Homebrew 按版本命名 Python,比如 python@3.13,先看装了哪些、有谁依赖它:
brew list --formula | grep '^python'
brew uses --installed python@3.13
brew uses 列出了别的 formula,说明它们需要这个 Python,只要它们还在,Homebrew 就会拒绝卸载,要么先卸掉依赖它的软件,要么留着这个版本。没有依赖时 brew uninstall python@3.13 就能卸掉,brew autoremove 会顺带清掉其他没人再需要的依赖。卸载 Homebrew 本身是另一件大得多的事,见卸载 Homebrew。
卸载 pyenv 的某个版本,或者整个 pyenv
pyenv 的 README 说,旧版本用 pyenv uninstall <版本号> 卸载,pyenv prefix <版本号> 能看到某个版本的目录。插件卸载时可能还会做额外的事,比如 pyenv-virtualenv 会把关联到这个版本的虚拟环境一起删掉。
pyenv versions
pyenv uninstall 3.11.9
想把 pyenv 整个卸掉,README 的做法是先从 shell 启动文件里删掉所有 pyenv 的配置行,再用 rm -rf $(pyenv root) 删掉它的根目录,装在里面的所有 Python 会一起被删除,用 Homebrew 装的 pyenv 最后再执行 brew uninstall pyenv。删之前先单独跑一次 pyenv root,看清它打印出来的路径。
卸载 Anaconda 或 Miniconda
Anaconda 的卸载说明和对应的 Miniconda 说明在 macOS 上都是同样三步:
- 把 conda 的初始化代码从 shell 配置里撤掉,先执行
conda activate,再执行conda init --reverse --all。 - 删掉安装文件夹,Anaconda 说它可能在个人文件夹里,也可能在
/opt下,取决于你当初怎么装的,conda info --base会打印实际位置,常见的是~/anaconda3、~/miniconda3、/opt/anaconda3或/opt/miniconda3,/opt下的要用sudo。 - 可选,删掉隐藏的配置和数据文件
~/.condarc、~/.conda和~/.continuum,如果有自定义设置、以后还打算重装,Anaconda 建议保留.condarc。
官方也提醒 rm -rf 不会确认、删了也撤不回来,回车之前先核对路径。你建的环境在安装文件夹里或 ~/.conda 下,需要的环境先用 conda env export -n <环境名> > env.yml 导出一份。
卸载 nodejs.org 安装的 Node.js
官方的 macOS 安装包其实是两个包合在一起,Node 自己的安装器定义里把它们登记为 org.nodejs.node.pkg 和 org.nodejs.npm.pkg,安装完成页写的是 node 装到 /usr/local/bin/node、npm 装到 /usr/local/bin/npm(安装器源码),npm 那个包还会把 npx 从 /usr/local/lib/node_modules/npm 链接进 /usr/local/bin。
删之前先看这两个包写了哪些文件:
pkgutil --pkgs | grep -i nodejs
pkgutil --pkg-info org.nodejs.node.pkg
pkgutil --files org.nodejs.node.pkg | head -50
--pkg-info 显示安装位置,文件列表是相对这个位置的路径。按两份列表删,核心是 /usr/local/bin/node、npm、npx 和 /usr/local/lib/node_modules/npm 这个文件夹。整个 /usr/local/lib/node_modules 删之前先看一眼里面,你用 npm install -g 装的全局包也在这里。最后执行 sudo pkgutil --forget org.nodejs.node.pkg,org.nodejs.npm.pkg 也同样处理一次,这一步只删收据。
卸载 Homebrew、nvm、fnm 或 Volta 管理的 Node
Homebrew: brew uninstall node,或者带版本号的 node@20 这类 formula,brew uses --installed node 能看到谁依赖它。
nvm: nvm ls 列出已装版本,nvm uninstall <版本号> 卸掉其中一个,给这个版本装的全局包也跟着一起没了。要卸 nvm 本身,nvm 的 README 的步骤是先执行 nvm unload,删掉它的目录($NVM_DIR,默认是 ~/.nvm),再从 shell 配置里删掉 NVM_DIR 那行 export 和加载 nvm.sh、bash_completion 的几行。nvm 不支持用 Homebrew 安装,如果你的 nvm 是 Homebrew 装的,用 brew uninstall nvm 卸。
fnm: 用 fnm list 和 fnm uninstall <版本号> 管理版本,fnm 的 README 说卸载 fnm 就是删掉它的文件夹,再把 shell 配置里提到 fnm 的内容删掉,比如 eval "$(fnm env ...)" 那一行。它在 macOS 上默认的数据文件夹是 ~/Library/Application Support/fnm,较早的安装用的是 ~/.fnm,用 Homebrew 装的还要再执行 brew uninstall fnm。
Volta: 按 Volta 文档,删掉 ~/.volta 目录,再删掉 shell 配置里提到 Volta 的那两行。
清掉 shell 启动文件里的 PATH
安装包和版本管理器会往下面这些文件里加几行,软件卸掉了,这几行还留着:
grep -n -E 'python|Python.framework|pyenv|conda|nvm|fnm|volta|node' ~/.zshrc ~/.zprofile ~/.bash_profile ~/.bashrc ~/.profile 2>/dev/null
输出会给出每处匹配所在的文件和行号,用文本编辑器打开,删掉属于已卸软件的那些行,指向 Python.framework 的 export PATH=...,pyenv init 相关的几行,conda init --reverse 没能执行时留下的 >>> conda initialize >>> 整段,nvm 和 fnm 的几行,还有 Volta 那两行,认不出来的行先别删。改完开一个新的终端窗口,已经开着的窗口还用着旧的 PATH,当前窗口里可以用 hash -r 让 zsh 忘掉记住的命令位置。
留下来的缓存和数据
卸载解释器不会顺带清掉它的包缓存:
| 缓存 | 位置 | 怎么清 |
|---|---|---|
| pip | macOS 上默认在 ~/Library/Caches/pip,pip cache dir 显示当前用的位置 |
卸掉最后一个 pip 之前执行 pip cache purge,或者直接删文件夹 |
| npm | ~/.npm,包在 ~/.npm/_cacache |
npm cache clean --force,或者 Node 卸掉之后删文件夹 |
| conda 包 | 安装文件夹里的 pkgs,或 ~/.conda/pkgs |
随安装文件夹一起删,~/.conda 可选 |
macOS 上的默认位置和 pip cache purge 来自 pip 的缓存文档,npm 的缓存文档则提醒,还在用 npm 的时候通常没必要清缓存,它会自我修复,Node 已经卸掉的话,那个文件夹就只是一堆数据了。
项目里的虚拟环境要单独处理,用已卸载的 Python 建的 .venv 指向一个不存在的解释器,直接就不能用了,删掉后用留下的那个 Python 按项目的 requirements.txt 或锁文件重建。为旧版 Node 编译过原生模块的 node_modules 也是一样。
Mole 在这里能做什么
Mole 不卸载解释器,也不卸载版本管理器,这部分用上面的命令。卸完以后清缓存时它用得上,pip 在 macOS 上默认的 ~/Library/Caches/pip 会在「清理」的「App 缓存与日志」里单独列一行,~/.cache/pip(有些配置用的 XDG 位置)则列在「开发工具」的 pip 缓存里,这两行默认勾选,pip 需要时会重新下载。「开发工具」里还会把 npm 的 _cacache 和 _npx 列出来但默认不勾,因为下次安装还要重新下载,另有一组默认勾选的「npm 缓存中不再使用的数据」,是 npm 自己的索引已经不再引用的缓存文件,还有 npm 日志,以及默认不勾的 Conda ~/.conda/pkgs。不勾的行在你选之前一直不勾,确认之前什么都不会删。npm 的规则为什么这么定,见 Mole 清的 npm 缓存为什么比 npm cache verify 少,其他工具链见清理开发缓存。
验证
开一个新的终端窗口,执行:
which -a python3 node
python3 --version
node --version
已经卸掉的那一份不该再出现。如果只剩 /usr/bin/python3,那是系统自带的,正常。原本就想把 Node 全卸掉的话,node 报 command not found 才是对的结果。旧版本还能运行,说明它的 PATH 行还留在某个 shell 文件里,或者另一个安装包在别处又放了一份,回到第一步重新查。
常见问题
Mac 上怎么卸载 Python?
先用 which -a python3 看是哪一份,再按安装方式卸,Homebrew 用 brew uninstall python@3.x,pyenv 用 pyenv uninstall,python.org 安装的就删掉「应用程序」里的文件夹、框架里对应的版本和 /usr/local/bin 里的链接。/usr/bin/python3 属于 macOS,不要删。
Mac 上怎么卸载 Node.js?
Homebrew 用 brew uninstall node,nvm 用 nvm uninstall <版本号>,nodejs.org 安装包就删掉 /usr/local/bin/node、npm、npx 和 /usr/local/lib/node_modules 下的 npm 文件夹,再忘掉 org.nodejs.node.pkg 和 org.nodejs.npm.pkg 两份收据。
Mac 上怎么彻底卸载 Anaconda?
执行 conda activate 和 conda init --reverse --all,删掉 conda info --base 报告的安装文件夹,比如 ~/anaconda3 或 /opt/anaconda3,可选再删 ~/.condarc、~/.conda 和 ~/.continuum。
macOS 自带的 Python 能删吗?
不能。Python 官方文档说 /usr/bin/python3 由 Apple 控制,Apple 和第三方软件都在用,任何时候都不要修改或删除,另装一份放在旁边,用 PATH 决定运行哪一份就行。
卸载 Python 之后为什么 python3 还能运行?
要么 PATH 里还有另一份,常见的是 macOS 自带的 /usr/bin/python3,要么终端还用着旧的 PATH。开个新窗口执行 which -a python3,再把 ~/.zshrc 或 ~/.zprofile 里残留的 PATH 行删掉。