
在Macbook Pro上折腾Homebrew最痛苦的时候不是编译报错而是brew install敲下去之后终端就像被点了暂停键。我的机器是M1 Max日常跑项目非常流畅可只要终端里蹦出Updating Homebrew...这几个字接下来等多久全看网络心情。最夸张的一次我等了快五分钟最后等到的是fatal: unable to access https://github.com/Homebrew/homebrew-core.git/直接白给。后来我把brew的源彻底切到了国内镜像这个问题才算真正解决。这篇文章我就把在Macbook Pro上修改brew源的完整思路、具体命令和一路踩过的坑写下来如果你也经常遇到brew update卡死、安装软件卡在Downloading阶段或者频繁报网络错误这篇应该能帮上忙。1. 换源之前先搞清楚brew到底在“拖”什么1.1 brew的三层结构与各自的下载瓶颈很多人对brew的印象就是一个包管理器敲一条命令就能装软件但它的背后其实分了好几层网络请求。想要把源改明白先得知道brew每次都在访问哪些地方。第一层是brew本体也就是Homebrew程序自身的代码仓库。它默认从github.com/Homebrew/brew拉取更新负责你敲的brew update命令以及内核逻辑的升级。第二层是软件包仓库3.x及更早版本的brew会通过git clone完整下载homebrew-core和homebrew-cask仓库里面存着几十万个软件包的描述信息、版本号、依赖关系和安装脚本。到了4.x版本官方改成默认通过JSON API从formulae.brew.sh/api获取这些信息不再需要整仓库clone了。第三层是bottles二进制包也就是真正要下载的编译产物。这些预编译包存放在ghcr.ioGitHub Container Registry上体积从几MB到几百MB都有。理解了这三层结构你就能明白为什么brew会卡住。brew本体和core仓库的数据量虽然不算特别大但git clone本身是对GitHub服务器的持续请求bottles的下载直接就是从海外对象存储拉大文件API也是海外接口。任何一个环节出现网络拥塞、超时、DNS解析异常终端就会显示卡住或者直接报错。实际表现出来就是三种典型症状brew update进度条长时间不动brew install卡在Updating Homebrew...下载软件时速度只有几十KB每秒最后还可能中断。1.2 镜像源为什么能解决问题镜像源做的事情本质上就是复制搬运。我们会用到的几个国内镜像站比如清华TUNA、中科大USTC、阿里云都会定时同步Homebrew官方仓库、bottles和API数据。你把它想象成一家本地中央厨房官方菜单长什么样中央厨房就原样抄一遍你不需要每次都跑去海外总店点餐出门左转就能拿到同样的菜。内容一致这是换源的前提。镜像站同步的频率直接决定了数据的时效性主流镜像站一般每隔几小时到一天就会同步一次对普通家用场景来说足够用了。你在Macbook Pro上配置完镜像源之后brew install执行的逻辑没有任何变化只是下载请求从远距离的海外服务器转移到了本地网络路径延迟和丢包率都会明显下降。不过有一点要提前说明镜像源只能加速它同步过的那部分内容。如果你的某个软件包在镜像站还没有收录或者下载地址被软件本身写死到了官网换源也救不了。这个问题后面在问题排查部分还会再讲。2. 准备工作确认环境、记录配置与选择镜像2.1 确认Macbook Pro的CPU架构与brew安装位置很多人换源失败不是因为命令写错了而是因为搞不清楚自己的Macbook Pro到底属于哪一派。苹果从2020年开始把Macbook Pro切换到Apple Silicon芯片也就是M1、M1 Pro、M2等系列但此前很长一段时间市面上流通的还有Intel版本。不同架构的Macbook ProHomebrew的安装路径完全不同。在终端里执行uname -m就可以快速判断。输出arm64说明是Apple Silicon输出x86_64说明是Intel架构。Apple Silicon的brew通常安装在/opt/homebrew目录下Intel版则安装在/usr/local目录。如果你想再次确认可以用which brew命令查看brew可执行文件的具体路径。还有一个容易踩的坑有些Apple Silicon用户因为兼容性问题装了Rosetta版终端或Rosetta版brew此时uname -m显示的是x86_64brew路径却是/usr/local或者某个单独目录。这类环境里的远程源配置和原生Apple Silicon稍微有区别但它本质上还是走git remote那套逻辑下面的命令同样适用。总之路径不要凭空猜测用brew --repo来获取真实的仓库路径才是最稳妥的。2.2 记录当前源配置以便回滚在动手改任何配置之前先花一分钟看看现状。这一步很多人会跳过但等你想回滚的时候就后悔了。打开终端分别执行这几条命令记录下当前显示的remote地址。cd $(brew --repo) git remote -v如果你用的是旧版brewhomebrew-core和homebrew-cask还是独立的git仓库目录再用同样的方式检查一下cd $(brew --repo homebrew/core) git remote -v cd $(brew --repo homebrew/cask) git remote -v正常未改动过的机器这些remote地址应该都是https://github.com/Homebrew/xxx.git。把终端输出的地址复制到一个临时文本文件里存好作为回滚备份。另外还要检查一下环境变量。执行brew config找到里面跟HOMEBREW相关的行。如果之前你已经手动设置过一些环境变量或者安装过某些第三方工具帮你在shell配置里写过export语句那么后续操作时这些变量可能会覆盖或干扰新配置。建议把这些变量也记录下来。2.3 主流镜像源怎么选国内能用的Homebrew镜像源有好几个各有各的特点。我把目前比较主流的三个列出来方便你根据自己的网络情况选择。镜像源地址风格同步频率特点清华TUNAmirrors.tuna.tsinghua.edu.cn高老牌稳定文档详细bottles收录较全中科大USTCmirrors.ustc.edu.cn高速度快同步及时适合教育网用户阿里云mirrors.aliyun.com中高带宽充足访问速度快家宽用户友好个人实测下来的感受是电信和联通宽带下清华和中科大的表现都比较稳定移动宽带在部分地区访问阿里云会更顺畅。如果你不确定该选哪个可以先照着本文设置一个然后跑一次brew update如果出现网络超时再换成另一个源的地址。还需要注意一点同一个源的API域名和bottles下载域名虽然都属于一个镜像站但路径后缀略有不同。配置时最好严格对照该镜像站官方文档给出的路径不要凭感觉猜。后面我会给出清华源的完整地址作为例子其他源只需要替换前缀即可。3. 核心实操一步步把brew源切到镜像站3.1 新版brew4.x的环境变量方案Homebrew 4.0之后官方把软件包信息的获取方式从git clone改成了拉取JSON API。这本来是为了提速但在网络受限的场景下反而多了个新的瓶颈点。好在这个API域名和bottles下载域名都支持通过环境变量来覆盖。以清华源为例在终端里执行以下命令把API和bottles的地址都切到清华镜像。复制的时候注意区分大小写HOMEBREW_API_DOMAIN和HOMEBREW_BOTTLE_DOMAIN是两个不同的变量。export HOMEBREW_API_DOMAINhttps://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles/api export HOMEBREW_BOTTLE_DOMAINhttps://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles如果你用的是中科大源将前缀替换为https://mirrors.ustc.edu.cn/homebrew-bottles即可。阿里云则是https://mirrors.aliyun.com/homebrew/homebrew-bottles它的路径里多了一级homebrew目录。此时再执行brew config查看HOMEBREW_BOTTLE_DOMAIN和HOMEBREW_API_DOMAIN这两行的输出如果显示的已经是镜像站地址说明变量已经生效。但注意这种通过终端export设置的方式只在当前终端会话内有效关掉窗口再打开就会丢失。如果你只是想临时验证一下效果这样没问题如果想让配置长期生效就需要把它写入shell配置文件这一步我在3.3节会详细讲。3.2 旧版brew3.x的git remote方案如果你还在用3.x版本或者因为某些原因在配置文件里设置了HOMEBREW_NO_INSTALL_FROM_API1来强制使用git方式拉取仓库信息那么光有环境变量还不够需要把git仓库的远程地址也一起换掉。先换brew本体仓库的远程地址git -C $(brew --repo) remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git然后检查homebrew-core目录是否存在。如果存在继续执行git -C $(brew --repo homebrew/core) remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-core.gitcask仓库同理git -C $(brew --repo homebrew/cask) remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-cask.git注意清华源的git路径是/git/homebrew/brew.git中科大是/brew.git阿里云是/homebrew/brew.git。这三家的路径规则不完全一致设置前最好对照一下对应镜像站的说明页面。执行完git remote -v确认地址已经变成镜像站地址后再执行brew update验证效果。正常情况下brew update的输出速度会比官方源快非常多。对于4.x用户我不太建议为了强行适配git方案而设置HOMEBREW_NO_INSTALL_FROM_API1因为API方式已经比git clone轻量很多直接用API镜像源才是更优解。3.3 让配置永久生效并验证结果环境变量如果不持久化重启终端就前功尽弃。macOS现在默认的shell是zsh对应的配置文件是~/.zshrc。用文本编辑器打开这个文件把相关配置写进去。vim ~/.zshrc在文件末尾追加以下内容以清华源为例# Homebrew镜像源设置 export HOMEBREW_API_DOMAINhttps://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles/api export HOMEBREW_BOTTLE_DOMAINhttps://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles如果你用的是3.x版本还需要追加brew本体和core仓库的git remote配置。在~/.zshrc里可以加上这样两组变量Homebrew会优先读取这些变量来决定clone地址export HOMEBREW_BREW_GIT_REMOTEhttps://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git export HOMEBREW_CORE_GIT_REMOTEhttps://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-core.git保存退出后执行source ~/.zshrc让配置立即生效。有些用户把配置写到了~/.zprofile或~/.bash_profile里实际上对于交互式终端来说~/.zshrc更常用也更容易被正确加载。如果你发现配置写入后不生效先检查你自己当前的shell类型echo $SHELL输出的路径看看是不是/bin/zsh。验证换源是否成功最直接的方法就是观察实际下载过程。先执行brew update正常情况下速度会快很多也不会再卡在Updating Homebrew...。然后随便安装一个体积稍大的软件比如brew install wget。下载阶段终端会显示Downloading from开头的链接如果这个链接是镜像站的地址说明bottles源已经生效。如果再配合brew config查看HOMEBREW_BOTTLE_DOMAIN变量双确认就万无一失了。4. 换源之后常见问题与排查实录4.1 常见报错速查表换源本身不算复杂但实际操作中会遇到各种稀奇古怪的问题。我把最常见的几种问题和对应的排查思路整理成了一个速查表建议你收藏备用。现象可能原因解决方案brew update后提示fatal: unable to accessgit remote没换成功重新执行git -C命令并用git remote -v确认地址安装时仍显示Downloading from ghcr.io环境变量没有写入配置文件检查~/.zshrc是否完整执行source重新加载API返回404或JSON解析失败API_DOMAIN路径不对对照镜像站文档检查是否有/api后缀换源后brew install速度依然很慢软件包官网下载源没走bottles确认该包是否有预编译包或检查下载链接是否指向官方站点提示homebrew-core is a shallow cloneclone不完整执行git -C $(brew --repo homebrew/core) fetch --unshallow环境变量看起来设置了但brew config不显示变量名拼写错误逐个检查export语句区分API和BOTTLE的大小写brew upgrade时校验和不匹配镜像源同步时序问题清空下载缓存并重试brew upgradesource ~/.zshrc后终端报错或样式丢失配置文件里存在冲突检查追加的export附近是否有重复的source语句或语法错误4.2 典型坑位详解与解法第一个坑是git remote明明改成了镜像站但brew update还是会卡。出现这种情况先别怀疑命令有问题检查一下brew的自动更新逻辑是否还在走别的路径。新版Homebrew在执行brew install时默认会在安装前触发一次brew update --auto-update如果这个更新任务慢安装也会跟着卡。可以设置HOMEBREW_NO_AUTO_UPDATE1来关闭安装前自动更新需要更新时手动敲brew update即可。这在网络不稳定的时候非常管用。第二个坑是cask源的404问题。brew install --cask安装图形应用时很多cask配置里写死的下载URL是软件官方提供的地址比如某些Adobe或Microsoft的产品发布地址根本不在Homebrew仓库里。这种情况换源无效cask源只负责查找安装清单真正的安装包仍要从软件官网下载。遇到这种情况解决思路是开一个下载加速代理或者去官网手动下载安装包。这不是brew源能解决的问题别在这上面浪费时间。第三个坑是镜像站同步滞后导致的校验失败。有时你执行brew upgrade某个包的SHA256校验一直报错大概率是镜像站的bottles和API信息更新不同步。解法很简单把~/Library/Caches/Homebrew/downloads目录下的残留缓存清掉等半小时到一个小时等镜像站同步完成后再重试。如果你装了多个源也可以临时切换到另一个镜像源来验证到底是同步问题还是本地问题。第四个坑是使用docker、conda等工具时它们会调用系统的git命令去访问github.com镜像站对这类请求无能为力。很多人的第一反应是brew换源没生效实际上是工具链里根本没有走brew的环境变量。排查时先确认发起网络请求的进程到底是什么再决定该配置哪个环境的源。4.3 还原到官方源的方法换源之后如果想恢复默认配置操作也不复杂。先把git仓库的远程地址改回官方地址。对4.x和3.x分别执行对应的命令以homebrew官方GitHub地址为例git -C $(brew --repo) remote set-url origin https://github.com/Homebrew/brew.git如果homebrew-core目录存在git -C $(brew --repo homebrew/core) remote set-url origin https://github.com/Homebrew/homebrew-core.git下一步是删除~/.zshrc里添加的export行。找到HOMEBREW_API_DOMAIN、HOMEBREW_BOTTLE_DOMAIN、HOMEBREW_BREW_GIT_REMOTE、HOMEBREW_CORE_GIT_REMOTE这些行全部注释掉或者删除。最后执行source ~/.zshrc再执行brew config确认变量已经恢复默认。如果你想连缓存也一并清理可以执行brew cleanup和rm -rf ~/Library/Caches/Homebrew这样下次安装时就是完全干净的状态。还有一点值得提醒不要同时配置多个镜像源的环境变量并期望它自动切换。brew只会读取这些变量当前的最终值同时设置多个源会导致请求混乱。正确的做法是选定一个源其他变量都注释掉需要切换时再修改对应变量的值。写在最后我的实际使用体会换了源之后我这边最大的变化是brew install的节奏从等半天不知道成功没有变成了刷一下就装完。我记得最清楚的一次是重新安装一套开发环境需要三个brew包加两个cask应用整个过程不到两分钟这在换源之前想都不敢想。后来我干脆在~/.zshrc里同时保留了一套镜像源配置和一套官方源配置的注释模板随时可以切换方便排查问题。从我踩过的坑来看换源这件事本身不是难点真正容易出问题的是忽略环境变量和git仓库之间的一致性。建议你在每次操作完都花十秒钟执行一下brew config只确认两个变量的值。等以后你习惯了镜像源的速度再回头看那些卡在Updating Homebrew...的截图就能理解一个好用的源对开发效率的影响有多大了。