1. 为什么要写这篇 Homebrew 安装实录
我手上这台是 M1 芯片的 MacBook,系统从 Big Sur 一路升到 Sequoia,中间重装过两次。每次重装完,第一件要干的事不是装微信也不是装 Chrome,而是先把 Homebrew 装回来。原因很简单:后面所有开发环境的搭建都靠它,装 Python、装 Node、装 PostgreSQL、装各种命令行小工具,基本一条命令解决。如果没有它,每个工具都要去官网翻下载页,找对应架构的安装包,手动拖进 Applications 或者 /usr/local/bin,那才是真正的折磨。
但 M1 这一代机器和 Intel Mac 在 Homebrew 的安装路径上有个根本区别,这也是很多人装完一脸懵的地方。Intel Mac 时代,Homebrew 默认把所有东西塞在/usr/local下面;而 M1/M2/M3 这类 Apple Silicon 机器,默认前缀变成了/opt/homebrew。这个路径差异会引发一连串问题:老教程里写的命令不适用、PATH 配置不对、装完了敲brew提示找不到命令、某些软件找不到依赖库。网上那些 2021 年前后的教程,大部分还在讲/usr/local那一套,照抄的话十有八九要踩坑。
这篇内容我打算把 M1 芯片下安装 Homebrew 这件事从头到尾讲透:为什么路径变了、安装脚本到底干了什么、网络卡住怎么处理、PATH 怎么配、装完之后怎么验证、遇到各种报错怎么排查。适合谁看?三类人最对口——刚入手 M 系列芯片 Mac 的新手、重装系统后要重新搭环境的开发者、以及照着老教程装了一半卡住的人。我不打算只给你一行安装命令,那玩意官网首页就有,我要讲的是那行命令背后发生了什么,以及它出问题的时候你怎么判断、怎么救。
2. M1 芯片为什么改变了 Homebrew 的安装逻辑
2.1 从 /usr/local 到 /opt/homebrew 的路径迁移
要理解这次变化,得先从 macOS 的目录约定说起。/usr/local这个路径在 Unix 传统里就是留给"本机管理员自己装的东西"的,系统自带的软件在/usr/bin、/bin,用户自己编译的往/usr/local放,这是几十年的习惯。Intel Mac 上的 Homebrew 顺应了这个传统,所有包的前缀(prefix)都是/usr/local,装出来的二进制在/usr/local/bin,库在/usr/local/lib,配置在/usr/local/etc。
M1 芯片出来后,情况变了。Apple Silicon 引入了全新的系统完整性保护机制,加上系统卷被拆成了只读的系统卷和可写的用户数据卷,/usr/local这个目录在 M 系列机器上虽然还存在,但它的所有权和写入权限处理方式和 Intel 机器不太一样。更关键的是,Apple 自己在 M 系列机器上推的是/opt目录作为第三方工具的落点。Homebrew 团队权衡之后,决定在 Apple Silicon 上把默认前缀改成/opt/homebrew。
这个改动带来的直接影响是:Intel Mac 和 M 系列 Mac 上的 Homebrew 是两套完全独立的安装,路径不重叠,互不干扰。听起来是好事,但对 M1 早期用户来说,这意味着网上能找到的所有教程(当时清一色是 Intel 路径)都不能直接用了。
注意:如果你在 M 系列机器上看到某个教程让你执行
sudo chown -R $(whoami) /usr/local,先停一下。这条命令是给 Intel Mac 修正/usr/local权限用的,在 M1 上执行不仅没用,还可能把系统某个角落的权限搞乱。
2.2 路径差异带来的连锁反应
前缀变了,一切依赖路径的东西都跟着变。我列几个最典型的连锁反应,你对照看看有没有中招:
- 命令找不到:
brew的可执行文件在/opt/homebrew/bin,这个目录默认不在 shell 的 PATH 里,所以装完之后直接敲brew会报command not found。 - 依赖库搜索失败:某些软件编译时要去
/usr/local/lib找依赖,但在 M1 上库在/opt/homebrew/lib,找不到就编译报错。 - Python 包安装异常:用 pip 装某些需要编译的包时,头文件和库的路径对不上。
- 老脚本失效:很多团队内部的部署脚本写死了
/usr/local/bin/xxx,在 M1 上跑不起来。 - 多版本共存混乱:你要是从 Intel Mac 迁移过来的用户,旧机器上的配置直接抄过来,PATH 里同时有
/usr/local/bin和/opt/homebrew/bin,谁先谁后决定了用哪个版本的软件,很容易出现版本错乱。
搞懂这些,你才能明白为什么"装 Homebrew"这件小事在 M1 上值得单独写一篇。
2.3 Rosetta 与原生 arm64 的选择
还有一层容易忽略的东西:架构。M1 是 arm64 架构,而大量老软件只有 x86_64 版本,Apple 提供了 Rosetta 2 翻译层来跑这些老软件。Homebrew 在这里的处理方式是:
| 安装位置 | 架构 | 适用场景 |
|---|---|---|
/opt/homebrew | arm64 原生 | M 系列芯片日常使用,首选 |
/usr/local | x86_64(经 Rosetta) | 需要跑只在 x86 下编译的老工具 |
也就是说,理论上你可以在 M1 上同时装两套 Homebrew,一套原生的在/opt/homebrew,一套跑在 Rosetta 下的在/usr/local。但我的建议是:除非你确实遇到某个工具只有 x86 版本且装不上,否则不要碰 Rosetta 那套。维护两套环境的成本很高,PATH 顺序、依赖混淆、升级不同步,全是坑。九成以上的常用开发工具现在都有 arm64 原生版本了,没必要给自己找麻烦。
判断某个包是不是原生 arm64,装完之后可以这样看:
brew info 包名输出里会标明它是 bottle(预编译二进制包)还是从源码编译,以及架构信息。也可以用file命令直接看二进制:
file /opt/homebrew/bin/某个可执行文件输出里出现arm64就是原生,出现x86_64就是 Rosetta 跑的。
3. 装之前必须做的几项准备
3.1 确认系统版本和芯片型号
动手之前先把底摸清。打开"关于本机",或者终端里敲:
sw_vers uname -msw_vers告诉你系统版本,uname -m告诉你架构。M 系列芯片的uname -m输出是arm64,Intel 机器是x86_64。这一步别看简单,我见过有人拿着 Intel 机器照着 M1 教程装,然后跑来问为什么路径是/usr/local而不是/opt/homebrew——因为教程不适用你的机器。
系统版本方面,Homebrew 官方对 macOS 的支持有个最低要求,太老的系统版本会直接拒绝安装。近几年的版本基本都没问题,但如果你的机器还停在很旧的系统上,先升级系统再装。另外提醒一句,系统没装 Xcode Command Line Tools 的话,很多包编译会失败,安装脚本会自动触发安装,但那个下载过程在国内网络下可能很慢,甚至卡住,建议提前手动装好:
xcode-select --install这条命令会弹出一个对话框让你确认安装命令行工具,装完再继续。
3.2 网络环境的现实问题
这是国内用户绕不开的一环。Homebrew 的安装脚本要从 GitHub 拉取仓库,装包的时候要从 GitHub Releases 下载 bottle,而 GitHub 在国内的访问质量时好时坏,典型表现是:脚本跑到某一步卡住不动,或者报Failed to connect to raw.githubusercontent.com、curl: (7) Failed to connect之类的错误。
这里我不能给具体的网络加速方案,但可以给你几个思路方向:
- 如果你所在环境本身网络出口通畅,那直接跑就行,不用折腾。
- 如果卡在拉取阶段,可以试试调整 DNS,换成响应更快的公共 DNS,有时候能明显改善连接质量。
- 报错信息要仔细看,是卡在
raw.githubusercontent.com还是github.com还是formulae.brew.sh,不同域名指向不同的解决思路。 - 有些团队内网有自建的镜像源或者代理服务,问一下运维有没有可用的内网地址。
关键在于:把报错日志完整看清楚,定位是哪个域名连不上,再针对性处理,而不是盲目地反复重试。我见过太多人卡住就 Ctrl+C 重来,重试十几次都是同一个位置失败,因为问题根本没解决。
提示:安装脚本的执行过程是分阶段的,前半段拉代码,后半段配置环境。如果卡在前半段,重试有意义;如果每次都卡在同一个位置,说明那个资源确实访问不到,得换思路。
3.3 清理可能存在的旧安装残留
如果你之前装过 Homebrew 但没装干净,直接重装会遇到各种奇怪问题。先检查一下:
which brew ls -la /opt/homebrew 2>/dev/null ls -la /usr/local/Homebrew 2>/dev/null如果/opt/homebrew已经存在且里面有一堆东西,但你执行brew又报错,那说明是半残状态。处理办法是先把旧目录清理掉:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/uninstall.sh)"这是官方卸载脚本。如果连这个脚本都拉不下来,那就手动删:
sudo rm -rf /opt/homebrew删之前确认一下里面没有你自己手动放进去的重要文件。删完再重新走安装流程,干净的目录能避免九成以上的玄学问题。
4. 正式安装:脚本执行的完整拆解
4.1 一行命令背后的完整流程
官方推荐的安装命令就一行:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"看着简单,但它内部干了一堆事。拆开来看,整个流程大致分这几个阶段:
- 环境检测:脚本先判断你的系统版本、CPU 架构、当前 shell,决定装到
/opt/homebrew还是/usr/local。 - 确认提示:终端会打印一段说明,告诉你会装到哪里、需要按回车确认、可能需要输入密码。
- 拉取仓库:从 GitHub 克隆 Homebrew 的核心仓库到本地。
- 下载依赖:拉取 Homebrew 自身依赖的一些组件。
- 配置环境变量提示:装完后打印一段 PATH 配置指引,让你加到 shell 配置文件里。
- 更新索引:执行
brew update拉取 formula 索引。
整个过程最耗时的是第 3、4、6 步,网络好的话几分钟,网络差的话……你懂的。
4.2 执行过程实录与关键输出解读
实际跑起来大概是这样(以 zsh 为例,macOS 现在默认 shell 就是 zsh):
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" ==> Checking for `sudo` access (which may request your password)... Password:这里输入你的登录密码。注意,终端里输入密码是不显示字符的,别以为键盘坏了。
==> This script will install: /opt/homebrew/bin/brew /opt/homebrew/share/doc/homebrew /opt/homebrew/share/man/man1/brew.1 ... Press RETURN/ENTER to continue or any other key to abort:敲回车继续。
==> /usr/bin/sudo /usr/sbin/chown -R 你的用户名:admin /opt/homebrew ==> Downloading and installing Homebrew... remote: Enumerating objects: ... Receiving objects: 45% (xxxx/xxxx)这一段就是拉取过程,卡住大概率在这里。耐心等,或者按前面的思路排查网络。
==> Next steps: - Run these commands in your terminal to add Homebrew to your PATH: echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile eval "$(/opt/homebrew/bin/brew shellenv)" - Run brew help to get started - Further documentation: https://docs.brew.sh看到 "Next steps" 就说明装成功了。注意它给你的那两行配置命令,这是下一步必须做的事,不配置的话brew命令用不了。
4.3 PATH 配置:这一步不做过不了
脚本提示的那两行,本质是让 shell 每次启动时自动把 Homebrew 的 bin 目录加进 PATH。第一行是写进~/.zprofile文件,第二行是让当前会话立刻生效。执行完这两行,再验证:
brew --version能正常输出版本号就说明 PATH 配好了。如果你用的是 bash,配置文件不一样,对应的是~/.bash_profile或~/.bashrc。用 fish 的话语法又不同,脚本都会给你对应的提示,照着来就行。
这里有个细节值得说一下:~/.zprofile和~/.zshrc的区别。.zprofile在登录 shell 启动时读取,.zshrc在每次交互式 shell 启动时读取。Homebrew 官方让你写进.zprofile,是因为 PATH 这类环境变量设置一次就够了。但很多人的习惯把所有配置都堆在.zshrc里,这也不是不行,只是要注意别在两个文件里重复设置 PATH,否则 PATH 会越来越长,还可能造成顺序混乱。
4.4 验证安装是否真正成功
别只敲个brew --version就以为完事了,再跑几个检查:
which brew # 期望输出:/opt/homebrew/bin/brew brew doctor # 检查环境问题brew doctor是 Homebrew 自带的环境诊断工具,它会检查 PATH、权限、依赖等一系列项目,输出 "Your system is ready to brew." 就基本没问题了。如果它报了一堆 warning,别慌,按提示逐条处理,有些 warning 是无害的,比如某些第三方软件干扰。
再装个小工具试试水,验证下载和安装链路是否通畅:
brew install wget如果这个小包能顺利装上,说明整条链路都是通的。
5. 常见报错与排查手册
5.1 安装阶段的典型报错
我把这几年遇到过以及社区里高频出现的报错整理成一张表,方便你对照排查:
| 报错信息关键词 | 可能原因 | 处理思路 |
|---|---|---|
curl: (7) Failed to connect | 拉取脚本的域名连不上 | 检查网络出口,调整 DNS,看重试是否有改善 |
Failed to connect to raw.githubusercontent.com | 拉取安装脚本失败 | 换用可访问的镜像地址获取脚本 |
Error: Checksum mismatch | 下载内容不完整或被篡改 | 清缓存重试,检查下载源完整性 |
xcode-select: error: command line tools not installed | 命令行工具没装 | 先跑xcode-select --install |
Permission denied | 目录权限不对 | 检查/opt/homebrew所有者,按提示修正 |
command not found: brew | PATH 没配 | 执行brew shellenv那两行 |
卡在Receiving objects不动 | 网络传输慢或中断 | 等待或排查网络,别急着 Ctrl+C |
这里重点说两个。第一个是command not found: brew,这是新手最常遇到的,原因是装完之后没执行 PATH 配置那两行,或者配置写进了错误的文件。第二个是Permission denied,M1 上的/opt/homebrew所有者应该是你自己,如果不知怎么变成 root 了,用这条修:
sudo chown -R $(whoami):admin /opt/homebrew注意这里是/opt/homebrew不是/usr/local,别搞混。你在网上搜到的很多权限修复命令针对的是 Intel 路径,M1 上要改。
5.2 安装后的使用问题
装成功了不代表万事大吉,用起来还会有各种小问题。
问题一:装包速度慢。瓶颈主要在从 GitHub Releases 下载 bottle。可以看看brew是否支持走你环境里已有的加速配置,不同版本的 Homebrew 配置方式略有差异,核心是让下载流量走更快的路径。另外,某些包会从源码编译,那段时间取决于你的 CPU,M1 编译其实挺快的。
问题二:brew update报错。通常是本地仓库状态混乱,比如之前中途打断过。处理办法:
cd /opt/homebrew git status git stash brew update或者更暴力一点,直接brew update-reset,把仓库恢复到干净状态。
问题三:卸载残留。Homebrew 卸载不干净,重装后各种冲突。完整清理流程是:先跑官方 uninstall 脚本,再手动删残留目录。
# 官方卸载 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/uninstall.sh)" # 补刀,清理可能的残留 sudo rm -rf /opt/homebrew sudo rm -rf ~/Library/Caches/Homebrew sudo rm -rf ~/Library/Logs/Homebrew这几个缓存目录不清掉的话,下次装的时候可能读到旧的缓存内容,导致一些诡异问题。
5.3 几个容易忽略的隐蔽坑
这几个坑不太出报错,但会让你的环境慢慢变乱,属于"温水煮青蛙"型。
坑一:PATH 顺序。如果你 PATH 里/usr/local/bin排在/opt/homebrew/bin前面,那么当两个位置都有同一个命令时,会优先用/usr/local/bin里的。这在装了 Rosetta 版 Homebrew 的机器上是重灾区。检查方法:
echo $PATH | tr ':' '\n'看看两者的顺序,正常情况下/opt/homebrew/bin应该在前面。
坑二:多 shell 配置文件冲突。你可能既在.zprofile又在.zshrc里配了 PATH,重复执行导致 PATH 里有多个重复条目。检查一下:
echo $PATH | tr ':' '\n' | sort | uniq -d有输出就说明有重复,回去把多余的删掉。
坑三:brew cleanup的时机。这个命令清理旧版本包和缓存,能省不少磁盘空间。但别装完就急着跑,有些工具依赖旧版本。我的习惯是一个月跑一次,或者磁盘紧张的时候跑。
坑四:权限的连锁反应。如果你用sudo brew install装过包(这是错误做法),会导致相关目录权限变成 root,后面正常的brew install就会各种失败。永远不要给 brew 加 sudo,它自己会处理需要权限的情况。
6. 装完之后:让 Homebrew 真正为你服务
6.1 必装的基础工具清单
Homebrew 装好只是起点,接下来才是重点。我列一份自己每台新机器都会装的清单,供参考:
# 基础命令行工具 brew install wget curl git tree jq # 开发环境 brew install python node # 生产力工具 brew install --cask iterm2 visual-studio-codebrew install装命令行工具,brew install --cask装图形界面应用。这个区分要搞清楚,很多新手用brew install装 GUI 软件,怎么也装不上,就是没加--cask。
6.2 日常使用中最实用的几个命令
把下面这些记住,日常效率能提升一大截:
| 命令 | 作用 |
|---|---|
brew search 关键词 | 搜索可用的包 |
brew info 包名 | 查看包详情、版本、依赖 |
brew list | 列出已安装的包 |
brew outdated | 查看哪些包有新版本 |
brew upgrade | 升级所有包 |
brew upgrade 包名 | 升级指定包 |
brew uninstall 包名 | 卸载包 |
brew cleanup | 清理旧版本和缓存 |
brew doctor | 环境诊断 |
brew services list | 查看后台服务状态 |
其中brew services值得单独说,它可以管理那些需要常驻后台的服务,比如数据库、Web 服务器。启动一个服务:
brew services start postgresql它会注册成开机自启的常驻服务,比手动在终端里开一个窗口跑着方便多了。
6.3 我的个人使用心得
最后分享几个踩坑换来的体会。
第一,别追新。Homebrew 每次升级可能带来 breaking change,尤其是大版本更新。生产环境用惯了的机器,我不会无脑brew upgrade,而是先看brew outdated列出来的是什么,确认没有影响再升。有次我随手升级,结果某个依赖包升到新版本,旧的脚本跑不通了,排查了半天。
第二,锁版本有技巧。Homebrew 默认只保留最新版本,但有时候你需要特定版本。可以用brew pin 包名把某个包锁定在当前版本,禁止它被升级。解除锁定用brew unpin 包名。
第三,镜像和缓存能救命。网络环境不好的时候,配置一个可用的加速源或者利用好本地缓存,能省大量时间。brew cleanup之前想清楚,缓存清了之后下次装又要重新下载。
第四,M1 上的原生体验确实好。装 arm64 版本的包,编译速度和运行效率比 Rosetta 下快不少。尽量用原生版本,遇到只支持 x86 的包再单独想办法。
第五,定期brew doctor。它能在环境出问题之前给你预警。我现在养成习惯,每次装完一批新东西就跑一次,很多小问题及早发现及早处理,免得积累成大麻烦。
整个流程走下来,从最初的系统检测、网络排查,到正式安装、PATH 配置,再到装完后的验证和日常维护,每一步都有它的门道。M1 芯片带来的路径变化看似只是把/usr/local换成了/opt/homebrew,背后牵扯的是架构迁移、权限机制、生态适配的一整套问题。把这些搞清楚,你不只是会装 Homebrew,而是理解了 M 系列 Mac 上软件生态的运作逻辑,后面遇到其他工具的环境问题也能举一反三。