1. 为什么每个mac用户迟早都要学会用Homebrew
如果你刚接触Mac,大概率会遇到这样的场景:想装个wget、ffmpeg、htop,去官网找下载链接,发现要么是源码包需要自己编译,要么是dmg装完还要手动配置路径,要么干脆就是老版本不兼容新版macOS。折腾了半天,最后想卸载还找不到干净的卸载入口。
这就是包管理工具存在的意义。Homebrew(社区里习惯直接叫brew)是macOS上最主流的软件包管理工具,核心作用可以概括成一句话:用命令行搞定软件的安装、升级、卸载和依赖管理。它让你不用再满世界找下载页面、手动拖拽.app、处理各种隐藏的依赖关系,一条命令就能完成整个生命周期。
早期macOS没有官方包管理器,开发者装软件基本靠编译源码,普通用户靠dmg安装。但编译依赖是个无底洞,装A之前要先装B,装B之前又要装C,版本号还得对上。Homebrew就是在这个痛点下诞生的——它的定位是"macOS缺失的包管理器",对标Linux上的apt和yum,让Mac用户也能享受类似Linux包管理的便利。
文章会覆盖这几块内容:Homebrew能解决什么问题、安装卸载与国内网络下的加速方案、最常用的核心命令、安装软件时的路径与权限机制、以及日常使用中真正踩过的坑。无论你是刚摸到Mac的新手,还是已经用了几年但一直用dmg装软件的老用户,这篇都值得花十分钟读完。
有人可能会问:Mac App Store不是也能装软件吗?确实能,但App Store上架审核严格,很多命令行工具、开源软件、开发类工具根本不会上架。就算上架了,版本更新也可能落后。Homebrew恰好补上了这个缺口,而且它对开发者极其友好,这也是为什么几乎所有macOS相关的开发环境搭建教程里,第一步都是装Homebrew。
2. Homebrew的核心原理:一个Ruby脚本加三个目录
要真正用好Homebrew,先搞懂它的工作原理会事半功倍。网上很多教程直接丢命令,读者照着敲完了事,一旦出问题就不知道怎么排查,根源就是不懂机制。
2.1 Homebrew到底怎么运作的
Homebrew本体其实是一个用Ruby写的Git仓库,默认安装在/opt/homebrew(Apple Silicon芯片)或/usr/local(Intel芯片)。当你执行brew install xxx时,它做的事情远比"下载文件然后拷贝"复杂得多:
- 先解析这个软件包的所有依赖项,类似你去餐厅点菜,厨师会先确认仓库里有没有配菜,没有就先补货。
- 从预编译的瓶装包(bottle)下载对应系统的二进制文件,或者自动拉取源码在本地编译。
- 将文件安装到
Cellar目录(软件本体存放处),然后在bin目录创建软链接,让命令行可以直接调用。
这个设计的好处是:所有软件包都隔离在统一的目录结构里,卸载时删掉对应文件再加清理软链接,不会像dmg那样散落一堆文件在系统各个角落。
2.2 Homebrew的三个核心组件
完整安装Homebrew后,你实际上获得了三个相互独立又配合使用的工具:
| 组件 | 作用 | 典型命令 |
|---|---|---|
| brew | 包管理器主程序,管软件安装升级卸载 | brew install/brew upgrade |
| brew cask(现已合并进brew) | 管理GUI应用程序,装Chrome、VS Code这类带图标的软件 | brew install --cask google-chrome |
| brew services | 管理后台服务,如MySQL、Redis、PostgreSQL的开机自启与启停 | brew services start mysql |
很多新手搞不清install和install --cask的区别。简单理解:前者装的是命令行工具,后者装的是带图标的桌面应用。早期两者是分开的子命令,现在统一成了brew加参数区分。
2.3 为什么Homebrew安装路径如此讲究
Intel芯片时代,Homebrew安装在/usr/local,直接和系统目录混在一起。Apple Silicon芯片出现后,系统目录被/System卷锁定,普通用户没有写入权限。Homebrew于是改到/opt/homebrew,这也是为什么现在新电脑上brew命令路径和旧教程不一样。
如果你用的是M1/M2/M3芯片的Mac,看到教程里写/usr/local/bin/brew就要警惕,那多半是针对Intel芯片的旧教程。检查自己芯片的方法是左上角点击苹果图标 -> 关于本机,或者终端执行uname -m,输出arm64就是Apple Silicon,x86_64就是Intel。
知道安装路径还有个实际用途:如果以后要卸载Homebrew,或者手动排查某个软件装到哪了,直接看这几个目录就行。Cellar存软件本体,bin目录存可执行文件的软链接,Caskroom存GUI应用的安装包镜像。
3. 安装与卸载实操:涵盖国内网络环境下的加速方案
安装Homebrew本身很简单,官方一行命令就能搞定。但如果你在国内网络环境下,直接跑官方脚本通常会卡在下载阶段,理由大家都懂,这里不展开。我会给出完整的安装流程,包括官方方式和国内镜像加速方式,以及卸载时如何把残留清干净。
3.1 官方标准安装方式
打开终端(Terminal.app),执行:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"脚本会先检查系统版本、芯片类型、安装必要的依赖(如Command Line Tools),然后开始下载安装。整个流程可能需要几分钟,视网络状况而定。如果系统提示需要安装Command Line Tools,会弹出图形化窗口,点击安装即可。这个过程没有进度条白等的情况,耐心点就行。
安装完成后,终端会提示你执行两条echo命令把brew添加到PATH,Apple Silicon芯片的Mac是:
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile eval "$(/opt/homebrew/bin/brew shellenv)"Intel芯片的Mac则是:
echo 'eval "$(/usr/local/bin/brew shellenv)"' >> ~/.zprofile eval "$(/usr/local/bin/brew shellenv)"这里经常有人跳过,结果下次打开终端输入brew提示command not found,还以为是安装失败。实际上安装是成功的,只是PATH没配置好。
3.2 国内网络环境下的镜像加速方案
官方源托管在GitHub,国内下载速度非常不稳定,尤其是瓶装包动不动几十上百MB。推荐的做法是安装时直接用国内镜像,这里推荐清华TUNA镜像源或中科大USTC镜像源,二选一即可,我实测两者都稳定。
第一步,安装时替换脚本里的源地址:
/bin/bash -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"这套脚本会引导你选择镜像源(清华/中科大/阿里云),然后自动完成安装和源替换。注意这是社区维护的脚本,运行前可以先去对应仓库看一眼更新情况,确认脚本内容没被篡改过再执行。
如果你已经用官方脚本装好了,只是下载慢,可以直接手动换源。以清华大学镜像源为例:
cd "$(brew --repo)" git remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git cd "$(brew --repo homebrew/core)" git remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-core.git cd "$(brew --repo homebrew/cask)" git remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-cask.git换完源之后,还需要设置环境变量让brew下载瓶装包时走国内镜像:
echo 'export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles' >> ~/.zprofile source ~/.zprofile这样brew install下载瓶装包时就会从清华镜像拉取,速度会明显提升。
3.3 卸载以及清理残留
卸载Homebrew最干净的方式是运行官方卸载脚本:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/uninstall.sh)"脚本会移除/opt/homebrew(或/usr/local)下的Homebrew本体、相关链接、缓存目录等。但有些残留它不一定清得干净,我习惯手动再检查几个位置:
~/Library/Caches/Homebrew:下载的缓存文件,可以整个删掉~/Library/Logs/Homebrew:日志文件~/Library/Preferences/com.brew.*:偏好设置残留
如果你装过某些服务(比如用brew services start mysql跑过的MySQL),卸载Homebrew后这些服务可能还在运行,记得先停掉再卸载:
brew services stop --all3.4 安装后第一件事:跑一遍自检
安装完或者换完镜像源,先不要急着装软件,跑一下自检命令确保状态健康:
brew doctor这个命令会检查系统里可能干扰Homebrew运行的因素,比如冲突的环境变量、残留的安装文件、权限错误等。如果提示Your system is ready to brew,说明状态正常。如果有warning,按提示处理即可,大部分问题都能在提示里找到解决方案。
我见过不少人在这一步卡住,原因是在系统里装过其他包管理器(如MacPorts、Fink),或者手动往/usr/local写入过文件导致权限混乱。brew doctor的目的就是把这些潜在问题提前暴露出来,免得后续安装时灵异报错。
4. 最常用的Homebrew命令清单与实际场景演示
命令这东西,列一长串没人记得住。我按使用频率和实际场景分类,每一类配上真实的终端输出效果,你在自己终端里照着敲就能对比验证。
4.1 软件安装与卸载
安装一个命令行工具:
brew install wget安装过程会先解析依赖,比如wget依赖OpenSSL和libidn2,brew会自动一并安装。终端会有类似这样的输出:
==> Downloading https://formulae.brew.sh/api/formula/wget.jws.json ==> Downloading https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles/wget... ==> Pouring wget--1.21.4.arm64_sonoma.bottle.tar.gz 🍺 /opt/homebrew/Cellar/wget/1.21.4: 23 files, 3.4MB那行🍺开头的就是安装成功标志(文本环境里看不到图标也没关系)。
安装GUI应用加--cask参数:
brew install --cask google-chrome这里装的是Chrome浏览器本体,安装后可以在启动台找到图标,和从官网下载dmg安装的唯一区别是:后续升级可以用brew统一管理,不需要再去官网下载新版本。
卸载对应命令是:
brew uninstall wget brew uninstall --cask google-chrome4.2 查询与搜索
不知道某个软件是否存在,先搜一下:
brew search mysql输出会列出所有名字里带mysql的formula和cask,包括mysql、mysql-client、mysql-connector-c等。
查看某个软件包的详细信息:
brew info mysql这条命令会显示版本号、依赖项、是否已安装、安装路径、注意事项(比如MySQL需要额外执行初始化命令)等信息。
查看自己装了哪些包:
brew listbrew list --cask单独列出GUI应用,brew list --formula单独列出命令行工具。
4.3 更新与升级
Homebrew把"更新软件包目录"和"实际升级软件"分成了两步,这是个常见误区。
更新软件包目录(类似刷新App Store的更新列表):
brew update查看有哪些包可以升级:
brew outdated升级所有可升级的包:
brew upgrade升级指定软件包:
brew upgrade mysql升级完记得清理旧版本残留:
brew cleanup这条命令会删除旧版本的软件包文件和下载缓存,释放磁盘空间。运行brew cleanup --dry-run可以先看会清理哪些文件而不实际删除。
4.4 查看占用空间
Mac磁盘空间紧张是常态,Homebrew装的东西多了之后,占用可能好几GB。查看所有包的大小:
brew list --formula --verbose | awk '{print $1}'更好的方式是直接看Cellar目录的大小:
du -sh /opt/homebrew/Cellar这个命令会显示所有通过brew安装的软件总占用空间。我见过有人装了一堆开发环境,Cellar目录能到10GB以上,这时候就得评估哪些软件不再用了,及时卸载。
4.5 依赖树管理
家酿的依赖关系是自动管理的,但有时你想看看某个软件依赖了什么,可以用:
brew deps --tree wget会以树状图展示wget的所有依赖链。如果担心某个包被多个软件共享,卸载时会连带删除其他软件依赖的包,那要看:
brew uses wget这个命令列出所有依赖wget的软件包,如果有其他软件依赖它,卸载wget前就要慎重——不会真的卸掉依赖它的软件,但那些软件再启动时可能会缺组件。
5. 用brew services管理后台服务:MySQL、Redis、Nginx实战
命令行工具装完就能用,但有一类特殊的软件——后台服务类,比如MySQL、Redis、Nginx、PostgreSQL,它们需要常驻运行,手动管理进程会很麻烦。brew services就是干这个用的。
5.1 启动与停止服务
以MySQL为例,安装完之后它不会自动启动,需要手动执行:
brew services start mysql执行后终端提示:
==> Successfully started `mysql` (label: homebrew.mxcl.mysql)MySQL就作为后台服务跑起来了,即使关掉终端窗口也不会停。停止服务:
brew services stop mysql重启服务(改了配置后常用):
brew services restart mysql5.2 开机自启设置
brew services start默认会把服务注册到开机自启列表里。如果只想临时跑一次不要自启,用run参数:
brew services run mysql这个命令只启动服务但不会设置开机自启。查看当前所有服务状态:
brew services list输出类似:
Name Status User File mysql started user ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist redis started user ~/Library/LaunchAgents/homebrew.mxcl.redis.plist nginx stoppedStatus列是started就表示在运行,stopped表示没在跑。File列显示的是LaunchAgent plist文件路径,这就是开机自启的配置文件。
5.3 配置文件位置
brew services管理的服务,配置文件通常放在/opt/homebrew/etc/对应软件目录下。比如:
- MySQL:
/opt/homebrew/etc/my.cnf - Redis:
/opt/homebrew/etc/redis.conf - Nginx:
/opt/homebrew/etc/nginx/nginx.conf
修改完配置文件后,需要执行brew services restart 软件名让配置生效。
5.4 一个真实场景:Mac上一次性搭好本地开发环境
假设你从零开始搭一套本地Web开发环境,用brew services的效率比手动管理高得多:
brew install mysql redis nginx php brew services start mysql brew services start redis brew services start nginx三条命令搞定三个服务的安装和启动,还可以继续用brew services list随时查看状态。这套组合拳是我日常本地开发的标准配置,比用Docker桌面版轻量不少,占用内存也更小。
注意:用
brew services启动的服务,日志输出一般在/opt/homebrew/var/log/目录下,比如MySQL的错误日志是/opt/homebrew/var/log/mysql/error.log。排查服务启动失败问题,先看这里比瞎猜靠谱得多。
6. 常见报错与解决办法:从装不上到权限问题
Homebrew用起来整体很省心,但偶尔也会遇到几个顽固报错。我挑了几个出现频率最高的,把完整排查思路写出来。
6.1 安装卡在"Updating Homebrew"不动
现象:执行任意brew命令,终端卡在Updating Homebrew...半天没反应。
原因:brew每次运行命令前会尝试从Git远程仓库拉取更新。国内网络访问GitHub不畅时,这一步就会卡住。
解决:
export HOMEBREW_NO_AUTO_UPDATE=1这个环境变量让brew不再自动更新。写进~/.zprofile永久生效:
echo 'export HOMEBREW_NO_AUTO_UPDATE=1' >> ~/.zprofile或者直接换源,让拉取更新也走国内镜像。我推荐两个都做:换源解决下载速度,NO_AUTO_UPDATE解决命令执行的等待。
6.2 Error: Permission denied @ dir_s_mkdir
现象:执行brew install时报权限错误,提示无法创建某个目录。
原因:常见于Intel芯片Mac,Homebrew安装在/usr/local,该目录原本属于系统管理员,当前用户没有写入权限。早期教程会让你sudo chown -R $(whoami) /usr/local,这在旧系统可行,但高风险,不建议再盲试。
解决:现在的主流方案是直接把/usr/local的所有权交给当前用户:
sudo chown -R "$(whoami)":admin /usr/local注意这里仍然需要sudo,执行一次即可,之后所有brew操作都不用再输密码了。
6.3 Error: The brew link step did not complete successfully
现象:安装某个包时报链接失败,提示Could not symlink某个文件到/usr/local/bin。
原因:这个文件已经存在于/usr/local/bin,通常是因为之前用dmg或脚本装过同名软件的旧版本。brew不会强制覆盖,以免破坏已有环境。
解决:手动删除冲突的文件,然后重试链接:
sudo rm -rf /usr/local/bin/wget brew link wget如果不想手动找冲突文件,可以直接强制链接:
brew link --overwrite wget6.4 ERROR: Failed to build gem native extension
现象:装Ruby相关工具(比如Jekyll)时,编译原生扩展失败。
原因:缺少编译依赖。Ruby的某些gem需要C编译器(Xcode Command Line Tools)和部分系统库文件。
解决:先确认Command Line Tools装好了:
xcode-select --install再通过brew安装编译依赖:
brew install gcc make libffi处理完重试原命令,大概率就能过了。
6.5 Warning: libxml2 is not installed. But you have libxml2 from Mac OS X
现象:brew doctor提示系统自带的libxml2与brew的版本可能不兼容。
原因:macOS自带部分系统级库文件,brew装的是更新版本,二者共存容易引起编译混乱。多数情况下这个warning不影响日常使用,可以忽略。
解决:真的需要编译某些依赖libxml2的软件,可以通过设置环境变量指定brew的版本:
export LDFLAGS="-L/opt/homebrew/opt/libxml2/lib" export CPPFLAGS="-I/opt/homebrew/opt/libxml2/include"具体变量名以brew info libxml2里的提示为准。
6.6 Homebrew与Mac系统升级后的兼容问题
每次macOS大版本升级,都可能出现Homebrew某些包无法正常工作的情况。这通常是因为旧版本的包不兼容新系统内核,或者新系统的安全性策略更严格。
处理方法:升级完系统后,尽早执行一次brew update && brew upgrade,把所有的包更新到兼容新系统的版本。如果个别包迟迟不更新,可以用brew info 包名查看这个包是否有已知问题,或去Homebrew的GitHub仓库搜索对应issue。
7. 进阶技巧与效率提升:别名、批量操作与最佳实践
基础命令掌握之后,再分享几个我自己日常使用中总结的效率技巧,能让brew用起来顺手不少。
7.1 给常用命令设置别名
天天敲brew install和brew uninstall,手都累了。给终端设置别名:
alias bi='brew install' alias bu='brew update && brew upgrade' alias bci='brew install --cask' alias bcu='brew uninstall --cask' alias bl='brew list' alias bs='brew services'写到~/.zprofile后执行source ~/.zprofile立即生效。以后bs start mysql和brew services start mysql完全等价,省键盘敲击。
7.2 批量迁移:把已安装列表导出再导入
换新Mac或者想备份软件清单时,这个技巧很好用。
导出当前所有已安装的formula和cask清单:
brew list --formula > brew-formulas.txt brew list --cask > brew-casks.txt在新机器上批量安装:
brew install $(cat brew-formulas.txt) brew install --cask $(cat brew-casks.txt)注意两个脚本分开执行,避免混装出错。我换新电脑时全靠这套备份恢复,几分钟就把开发环境搬过去了。
7.3 查看某个软件的版本支持情况
是不是还在为"这个软件支持新系统吗"发愁?直接看:
brew info --json 软件名输出是一段JSON格式的信息,包含版本、依赖、系统兼容性说明等。用brew info也可以,但JSON格式适合脚本处理,比如提取版本号:
brew info --json wget --formula | python3 -c "import sys, json; print(json.load(sys.stdin)[0]['versions']['stable'])"7.4 适度使用第三方工具扩展
还有一些工具能让brew体验更好,比如:
- mas:管理Mac App Store应用,可以结合brew脚本一起安装。
- honey:纯文本描述软件包,适合快速查看某个包做了什么。
这些工具的安装也走brew:brew install mas,不作为必须推荐,知道有这回事儿就行。
7.5 重要best practice汇总
结合我自己的经验,整理几条避免踩坑的最佳实践:
- 保持Homebrew本体和软件包及时更新,别攒一年多才升一次,大版本升级容易滚出一堆坑。
- 定期执行
brew cleanup,我每个月跑一次,能清掉几百MB到1GB不等的旧版本和缓存。 - 不要用sudo运行brew命令。brew设计理念就是不需要提权,如果你发现某个操作必须要sudo才能执行,往往说明目录权限出了问题,优先修复权限而不是顶着sudo硬上。
- 所有brew相关的环境变量统一放
~/.zprofile,不要散落在多个配置文件里,方便排查问题时一眼看到全貌。 brew doctor不是摆设,换新机器或者长时间没维护时,先跑一遍再干活,能省下后面一大串莫名其妙的问题。
这套工具链我用了好几年,从Intel Mac一路换到Apple Silicon,从/usr/local路径换到/opt/homebrew路径,中间踩过无数坑,但这套流程整体依然是macOS上管理软件最靠谱的解决方案。最让我满意的一点是:所有软件来源统一、依赖关系清晰、卸载干净利落,不用再像过去那样在官网之间来回折腾找下载链接。只要你愿意花十分钟掌握这些命令,之后的日常使用就是长期收益,干净利落。