首页/新闻资讯/正文详情

Mac 上 Homebrew 换国内源:一键脚本解决 brew install 卡顿与超时

发布时间:2026/9/24 19:57:39 来源:云帆数科 栏目:资讯中心
Mac 上 Homebrew 换国内源:一键脚本解决 brew install 卡顿与超时
讲个真事上月给朋友的新 Mac 配环境brew install wget敲下去进度条直接卡在Updating Homebrew...环节快十分钟没动。我第一反应不是网不好而是这家伙的 Homebrew 还顶着默认的 GitHub 源在跑。在国内网络环境下Homebrew 从 brew、homebrew-core 到 bottle 二进制包全程走 GitHub 那几条链路卡、慢、超时几乎成了常态。这篇里的脚本就是我当时顺手整理的解决一件事在苹果电脑上一条命令把 Homebrew 默认源切成国内源没装过的直接带源装想还原、想卸载也有一键脚本兜底。适合刚入手 Mac 的开发者、被 brew install 折磨过的人也适合负责团队新机装机脚本的同学抄作业。1. 换源解决的不是慢而是 Homebrew 的下载链路问题很多人以为换源就是改个网址的事真正理解之后你会发现Homebrew 的下载链路比想象中要复杂这也是为什么网上经常出现我明明换了源怎么还是慢的疑问。1.1 一次 brew install 背后到底访问了哪些地址以我用 Intel Mac 和老版本 Homebrew 的体验来说一条brew install触发的东西有先检查 brew 本体所在的 Git 仓库是否落后git pull然后去拉取 formula 索引再根据平台架构去下载对应的 bottle 预编译包。这三个动作分别对应不同的下载地址brew 本体仓库和 homebrew-core、homebrew-cask 配方仓库默认都在github.com/Homebrew/下公式索引 API新版 Homebrew 默认从formulae.brew.sh/api/formula.jws.json拉取bottle 预编译包默认从ghcr.ioGitHub Container Registry下载这四条链路任何一条慢体现出来的结果都一样brew install卡在某个进度条或者干脆报curl超时。换源的本质就是把这几条链路的默认地址全部替换成国内可访问的镜像仓库而不是只换其中某一个。这也是我写脚本时坚持把HOMEBREW_API_DOMAIN、HOMEBREW_BOTTLE_DOMAIN、git remote 一起处理的原因。1.2 为什么网上很多换源教程没效果我见过不少人照着帖子改了HOMEBREW_BOTTLE_DOMAIN结果brew update依然卡死。查下来通常是漏了两处一是HOMEBREW_API_DOMAIN没设公式索引还在走官方接口二是 brew 本体仓库的 git remote 没切brew update那一下还是要跟 GitHub 打交道。补充一个细节如果你用的是较老的 Homebrew 版本它安装 formula 时还依赖 homebrew-core 这个本地 tap 仓库这意味着换源必须包含 homebrew-core 的 git remote 切换。而 Homebrew 4.x 以后默认走 JSON API反而没那么依赖本地 tap。所以脚本里我做了兼容处理本地存在 homebrew-core 目录就切不存在就直接走 API两边都不会出问题。2. 镜像源选型清华、中科大、阿里我用一份对比表说话国内能换的 Homebrew 镜像源不少但每个源同步策略、覆盖范围、抗压能力都不一样。选错了不是不能用是高峰期可能比官方源还慢。这里我把自己实际测过的几个源拉出来对比。镜像站brew/公式仓库bottle 下载API 接口个人评级清华 TUNA支持支持支持首选教育网线路快同步及时中科大 USTC支持支持支持老牌稳定适合中科大附近网络阿里云支持支持支持家宽线路好高峰期偶尔限速腾讯云支持支持支持覆盖面不错但文档相对少2.1 清华源为什么被推荐得最多清华 TUNA 镜像站在国内运维时间长homebrew-bottles这个目录下不光有 bottle 包还有对应的 API JSON 数据两者是同一条 URL 前缀下的不同路径。这样的好处是配置简单我只要把HOMEBREW_BOTTLE_DOMAIN和HOMEBREW_API_DOMAIN都指到同一个根域名Homebrew 就能自动拼出正确的下载路径。实际体验上清华源的同步延迟通常在可接受范围内不会出现官方发了新版本、镜像却要等好几天的情况。对大部分用户来说换源后速度提升最明显的场景就是brew install下载 bottle 包几百 MB 的东西官方源可能跑到一半丢连接清华源基本满速跑完。2.2 中科大源的特殊技巧中科大源有个特点它把brew.git、homebrew-core.git、homebrew-cask.git分别放在平级路径下而且对老版本 Homebrew 的兼容做得不错。如果你还在用某些特殊渠道装的旧版本 brewUSTC 会是更省心的选择。据说中科大建议对HOME_DIR下的 Homebrew 目录做remote set-url切换这个动作恰恰是我脚本里核心的操作。各家源地址差异主要就是 URL 前缀所以我给脚本预留了三个源参数实际使用中想换哪个改一个参数就行。3. install.sh 完整实现从零安装与已装切换两条路径这个脚本我写了两个功能分支。第一分支是检测到 Mac 上压根没装 Homebrew直接利用官方安装脚本支持的环境变量实现带着国内源完成安装第二分支是已装过 Homebrew用git remote set-url把仓库地址切到镜像并写入持久化环境变量。3.1 脚本的整体骨架脚本主要有四个动作选源、检测、切换、写入配置。我特意把选源放在最前面方便你改成自己常用的镜像#!/bin/bash set -euo pipefail # # install-mirror.sh # 用法: bash install-mirror.sh [tuna|ustc|aliyun] # 功能: Homebrew 一键换国内源未安装时自动带源安装 # MIRROR_FLAG${1:-tuna} case $MIRROR_FLAG in tuna) BREW_GIThttps://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git CORE_GIThttps://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-core.git CASK_GIThttps://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-cask.git API_DOMAINhttps://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles/api BOTTLE_DOMAINhttps://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles ;; ustc) BREW_GIThttps://mirrors.ustc.edu.cn/brew.git CORE_GIThttps://mirrors.ustc.edu.cn/homebrew-core.git CASK_GIThttps://mirrors.ustc.edu.cn/homebrew-cask.git API_DOMAINhttps://mirrors.ustc.edu.cn/homebrew-bottles/api BOTTLE_DOMAINhttps://mirrors.ustc.edu.cn/homebrew-bottles ;; aliyun) BREW_GIThttps://mirrors.aliyun.com/homebrew/brew.git CORE_GIThttps://mirrors.aliyun.com/homebrew/homebrew-core.git CASK_GIThttps://mirrors.aliyun.com/homebrew/homebrew-cask.git API_DOMAINhttps://mirrors.aliyun.com/homebrew/homebrew-bottles/api BOTTLE_DOMAINhttps://mirrors.aliyun.com/homebrew/homebrew-bottles ;; *) echo 未知镜像源: $MIRROR_FLAG可用值: tuna / ustc / aliyun exit 1 ;; esac提示不确定选哪个源的时候默认tuna就好。教育网、家宽、移动、联通我都试过综合表现最稳。3.2 分支一未装 Homebrew直接用国内源完成安装官方安装脚本本身就支持通过环境变量指定 git 仓库地址。很多人不知道这一点还在傻等官方安装脚本慢慢拉 GitHub这个做法太不推荐了。完整的安装分支如下if ! command -v brew /dev/null 21; then echo 未检测到 Homebrew使用带国内源的方式安装... export HOMEBREW_BREW_GIT_REMOTE$BREW_GIT export HOMEBREW_CORE_GIT_REMOTE$CORE_GIT export HOMEBREW_CASK_GIT_REMOTE$CASK_GIT export HOMEBREW_API_DOMAIN$API_DOMAIN export HOMEBREW_BOTTLE_DOMAIN$BOTTLE_DOMAIN /bin/bash -c $(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh) else echo 已检测到 Homebrew执行仓库源切换... brew_prefix$(brew --prefix) git -C $brew_prefix remote set-url origin $BREW_GIT core_tap$brew_prefix/Library/Taps/homebrew/homebrew-core cask_tap$brew_prefix/Library/Taps/homebrew/homebrew-cask if [[ -d $core_tap ]]; then git -C $core_tap remote set-url origin $CORE_GIT fi if [[ -d $cask_tap ]]; then git -C $cask_tap remote set-url origin $CASK_GIT fi fi这里需要注意brew --prefix在 Apple Silicon 机器上通常是/opt/homebrewIntel 机型是/usr/local用命令取出来的值比写死路径可靠得多。另外在新版 Homebrew 里homebrew-core 可能不会以本地 tap 的形式存在所以我都加了-d目录判断目录不存在就跳过不影响整体。3.3 分支二把环境变量写成持久化配置光切 git remote 还不够bottle 下载和 API 接口索引还要靠环境变量。所以脚本最后的动作是写入 shell 配置文件。这里注意几个细节macOS 默认 shell 是 zsh但不少人装了 bash所以脚本要自动检测写入前先把旧的export HOMEBREW_开头行清掉避免换源后残留旧配置导致脚本反复追加不要用echo $var file这种粗暴追加法要先清理再写入detect_profile() { if [[ -f $HOME/.zprofile ]]; then echo $HOME/.zprofile elif [[ -f $HOME/.zshrc ]]; then echo $HOME/.zshrc elif [[ -f $HOME/.bash_profile ]]; then echo $HOME/.bash_profile else echo $HOME/.zshrc fi } PROFILE$(detect_profile) sed -i /^export HOMEBREW_/d $PROFILE 2/dev/null || true cat $PROFILE EOF export HOMEBREW_API_DOMAIN$API_DOMAIN export HOMEBREW_BOTTLE_DOMAIN$BOTTLE_DOMAIN export HOMEBREW_BREW_GIT_REMOTE$BREW_GIT export HOMEBREW_CORE_GIT_REMOTE$CORE_GIT export HOMEBREW_CASK_GIT_REMOTE$CASK_GIT EOF echo 环境变量已写入 $PROFILE echo 执行 source $PROFILE 后建议先运行一次 brew update这里还隐藏了一个细节为什么连HOMEBREW_CORE_GIT_REMOTE这种新版本已经不太用的变量也要写因为老版本和不走 API 的配置模式下缺了它brew update依然会跑回官方地址。写全了兼容性最好代价无非是多几行 export。4. uninstall.sh 与残留清理卸载不完全比不卸载更难受Homebrew 卸载比安装更容易翻车。官方提供了 uninstall 脚本但它同样需要从 GitHub 拉取而且即使卸载完成shell 环境变量、缓存目录、日志目录都会残留。所以我做卸载脚本时把它分成三步还原源、卸载本体、清理残留。4.1 先用官方卸载脚本网络兜底方案再手动删除官方脚本能自动识别 brew 装在哪、要不要保留某些目录比手工rm -rf安全得多。所以在卸载脚本里我优先调用官方脚本只有命令失败才提示手动删除echo 第一步执行官方卸载脚本 if ! /bin/bash -c $(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/uninstall.sh) -- --skip-cache-and-logs; then echo 官方卸载脚本执行失败尝试手动删除 brew_prefix$(brew --prefix) if [[ -d $brew_prefix ]]; then rm -rf $brew_prefix echo 已删除 $brew_prefix fi fi--skip-cache-and-logs参数的意思是卸载时不用动缓存和日志目录这两个目录后面由我自己接管。如果你装了 MySQL、PostgreSQL 这类把数据放在$(brew --prefix)/var下的软件官方卸载脚本会提示你数据残留记得提前备份。4.2 清理环境变量与缓存目录卸载完成后~/.zprofile或~/.zshrc里的 export 行不会自己消失。下次新装 Homebrew 时这些残留变量会继续把新 brew 指向旧镜像不算致命但会带来为什么我重装还是这么慢的困惑。所以清理脚本要把它们一并处理echo 第二步清理 shell 环境变量残留 PROFILE$(detect_profile) sed -i /^export HOMEBREW_/d $PROFILE 2/dev/null || true echo 已从 $PROFILE 中移除 HOMEBREW_ 相关环境变量 echo 第三步清理缓存与日志目录 rm -rf $HOME/Library/Caches/Homebrew rm -rf $HOME/Library/Logs/Homebrew echo 缓存与日志已清理写完这个脚本我特意测试过先手动往 zshrc 里塞了几行export HOMEBREW_BOTTLE_DOMAIN...跑完脚本后grep -n HOMEBREW ~/.zshrc输出为空清理得很干净。另外临时文件目录、旧版安装器留下的/Library/Developer/CommandLineTools是否要删看个人需求一般不建议动系统工具链。5. 换源后的验证与常见坑环境变量、权限和缓存这三道坎脚本写完了不代表万事大吉。我在测试时踩过几个坑每一步都有对应的排查方法这里按先验证、后处理坑的顺序说。5.1 换源是否生效看这三处输出第一处看brew config。终端里执行brew config正常情况下能看到类似下面的输出HOMEBREW_BOTTLE_DOMAIN: https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottlesHOMEBREW_API_DOMAIN: https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles/api如果这里还是空或者写着ghcr.io那就是环境变量没 load 进来执行source ~/.zprofile再重开一个终端会话试试。第二处看 brew 本体的 git remote。执行git -C $(brew --prefix) remote -v输出里的origin应该指向mirrors.tuna.tsinghua.edu.cn开头的地址如果还是github.com/Homebrew/brew.git说明切换分支没有真正生效。第三处重新装一个包观察下载 URL。挑一个包比如brew install htop在下载 bottle 时注意终端输出的地址。如果是指向清华或者中科大源的homebrew-bottles说明 bottle 路径没问题。5.2 权限问题Cannot write to /opt/homebrew的根源Homebrew 对安装目录的属主非常敏感。有些时候我们为了装软件会对/opt/homebrew或者/usr/local执行sudo chown -R但某些文件属主还是 root导致brew update报出权限类的错误。这种问题用脚本没法根治正确的检查姿势是ls -ld $(brew --prefix)输出应该显示当前用户有读写权限。如果没有执行sudo chown -R $(whoami):admin $(brew --prefix)如果权限修复后brew update依然报错可以用brew doctor看看还有什么历史遗留问题。说实话很多 Mac 上 Homebrew 的怪毛病brew doctor都能直接给出修复建议这是最被低估的排查命令。5.3 缓存导致的假换源换源最隐蔽的坑是缓存。你换源之前Homebrew 已经把某些软件的下载地址缓存到了~/Library/Caches/Homebrew。换源后再装同一个包时如果缓存里有对应版本的下载记录它可能还在用旧的下载地址做校验甚至直接复用断点缓存的数据。遇到这种情况我的经验是换源后先做一次彻底清理rm -rf $HOME/Library/Caches/Homebrew/downloads然后重新安装目标软件。别嫌这一步多余它能消灭九成换源没效果的误判。6. 周边工具的联动pip、npm、Jenkins 换源思路与 Homebrew 一致Homebrew 这套换源逻辑其实能复用到很多其他包管理器。近期常看到有人搜 pip 国内源、npm 国内源、Jenkins 插件国内源底层套路惊人地相似定位默认下载地址改成镜像站对应路径然后写入配置文件持久化。6.1 pip 和 npm 的换源操作pip 如果觉得安装第三方库慢最简单的是执行pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple这条命令和 Homebrew 写入HOMEBREW_API_DOMAIN的思路一模一样都是把从哪里下载包这个配置写进用户级配置文件。npm 则是npm config set registry https://registry.npmmirror.com反观 Jenkins 插件中心本质上就是把update-center.json的下载地址替换成 Jenkins 官方中文镜像提供的 URL配置完重启 Jenkins 后插件安装速度会有肉眼可见的提升。6.2 换源这几个通用坑跨工具都成立我踩过这么多换源方案后发现不管换什么源坑基本都是那几类一觉醒来镜像站同步滞后导致装到了旧版本缓存没有清理导致下载的还是旧地址配置文件格式写错导致工具直接罢工。所以无论换哪个源建议遵循同一个流程先备份原配置、再修改、然后验证。Homebrew 这套脚本只是把这个流程自动化了核心方法论是可以迁移到所有包管理器的。顺便说一句脚本里的源地址如果哪天发现失效先去对应镜像站的首页确认路径是否变动Homebrew 镜像的 URL 组织方式偶尔会调整改一下case分支里的地址就能继续用。

相关推荐

Gemma 4本地部署实战:从Ollama安装到Python调用全流程
Gemma 4本地部署实战:从Ollama安装到Python调用全流程

最近后台收到不少留言,都是关于“Gemma 4 本地AI”的。说实话这个消息一出,玩本地模型的圈子确实热闹了一阵,毕竟Gemma系列一向以开源、轻量、能吃下低配硬件著称,这次到了Gemma 4,连26B MoE这种大参数版本都有不少人直… · 2026/9/24 19:57:39

PySide/PyQt表格多格式录入与主从表事务保存实战
PySide/PyQt表格多格式录入与主从表事务保存实战

最近在给仓库部门改造一套材料入库工具,表格里除了普通文本,还要能直接录入日期、选仓库、填数量、勾选抽检状态,同时底部需要把入库单和明细行一起联动展示、一起保存。这个需求放在 PySide/PyQt 项目里相当典型,几乎可以当成一个… · 2026/9/24 19:57:39

算法面试必考:螺旋矩阵的两种思路与避坑指南
算法面试必考:螺旋矩阵的两种思路与避坑指南

刷力扣热题100的朋友,螺旋矩阵这道题基本是绕不开的。它排在数组章节比较靠前的位置,题号是54,在hot100列表里序号大概是第14,所以很多刷题攻略里叫它“螺旋矩阵(14)”。别看它名字听着玄乎,本质… · 2026/9/24 19:57:39

企业文档管理本地化AI路线图:从硬件选型到落地实践
企业文档管理本地化AI路线图:从硬件选型到落地实践

1. AI主机热起来之后,企业为什么开始认真考虑本地化最近大半年被问得最多的一个问题:AI主机都买回来了,文档管理这块的本地化AI路线图到底怎么画?问这个问题的人背景差异很大,有IT负责人,有行政总监&#x… · 2026/9/24 20:28:33

车辆检测与计数实战:基于YOLO格式数据集训练到部署全流程
车辆检测与计数实战:基于YOLO格式数据集训练到部署全流程

简介:这是一份面向YOLO系列算法的车辆检测与计数数据集,围绕1304张车辆图像构建,覆盖汽车、摩托车、公共汽车和卡车四类常见车辆目标,适用于入门级目标检测项目或算法验证。压缩包内共2000个文件,其中包含1089个XML标注… · 2026/9/24 20:28:33

消息队列实战指南:异步、解耦与削峰的核心原理与常见坑
消息队列实战指南:异步、解耦与削峰的核心原理与常见坑

做了快十年的后端开发,如果让我只选一个“投入产出比最高”的中间件,我会毫不犹豫把票投给消息队列。你想想,后面只要有老系统要对接、流量突然冲高、服务之间互相等待超时这些破事,最后基本都是靠消息队列来兜底。它不是什么花哨… · 2026/9/24 20:28:33

LSTM+GNN时间序列预测实战:从eICU数据预处理到模型训练
LSTM+GNN时间序列预测实战:从eICU数据预处理到模型训练

简介:这份代码包围绕长短期记忆网络与图神经网络相结合的混合时序预测实现,面向计算机、电子信息、数学等专业学生以及需要构建时序预测模型的开发者,适用于课程设计、期末大作业和毕业设计等场景。包内完整覆盖模型训练、动态图构建、数据预… · 2026/9/24 20:28:33

从Web访问到GUI操作:智能体工程化落地的关键实践
从Web访问到GUI操作:智能体工程化落地的关键实践

1. 为什么这个赛道突然火了:从"能聊"到"能干活"的分水岭过去两年我一直在跟 Agent 相关的项目打交道,坦白说,早期大多数号称"智能体"的产品,本质上就是一个套了层记忆功能的聊天机器人。你让它查个… · 2026/9/24 20:28:33

系统架构复杂度治理:活结-活络-活扩元模型实践指南
系统架构复杂度治理:活结-活络-活扩元模型实践指南

三月十号,团队关起门做了一次内部架构复盘,主题是“系统复杂度到底怎么治理”。那天产出的结论整理成了两版,第一版是常规的问题清单和改进项,第二版则更像一个能反复使用的思考框架——我们内部给它起了个名字叫“活结-活络-活扩… · 2026/9/24 20:28:15

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13

1D-CNN时间序列建模实战:从Conv1d原理到工业落地
1D-CNN时间序列建模实战:从Conv1d原理到工业落地

简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26

柔软的L:汉语语流中被忽视的舌肌张力控制
柔软的L:汉语语流中被忽视的舌肌张力控制

1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码