如果你刚换了Mac,或者正打算把开发环境迁到macOS上,那么十有八九会听到一个词:Homebrew。它是macOS上最流行的软件包管理器,作用一句话就能说清:帮你用命令行快速安装、升级、卸载各种软件和库,同时自动处理依赖关系。很多开发者把它称为“macOS 缺失的包管理器补丁”,从Python、Node.js、OpenJDK到MySQL、Chrome、微信,都能通过它一键搞定。
这篇文章不打算讲那些官网就能查到的抽象概念,而是围绕“Homebrew的作用及基本命令”这个主题,把安装、日常命令、常见报错、以及几年下来踩过的坑全部过一遍。不管你是刚接触Mac的小白,还是已经被brew折磨过的老用户,应该都能在里面找到点有用的东西。先放个结论:这工具值得你花半小时学会,之后能帮你省下无数找安装包、配环境变量的时间。
1. Homebrew到底是什么,为什么Mac开发者离不开它
1.1 先理解包管理器这件事
如果你以前用Windows比较多,第一次接触包管理器可能会觉得陌生。其实可以把它理解成“命令行版的应用商店”,但比应用商店更贴近开发者场景。应用商店装的是面向普通用户的APP,包管理器装的是开发过程中的各种依赖、编译工具和库。你执行brew install ffmpeg,它会把ffmpeg本身,连同它依赖的x264、libvpx、mp3lame等一系列库全部装好,不需要你手动去各个项目官网下载dmg或源码包。
包管理器最大的价值有三点:一是自动化,安装第三方库时不用手动管依赖;二是版本可控,想升级就升级,想锁版本就锁版本;三是卸载彻底,不像某些dmg软件一样拖进废纸篓还会留一堆配置文件。macOS本身用的包管理机制并不像Linux那样系统化,App Store只覆盖一部分图形应用,大部分命令行工具和开发者库都散布在各个网站,Homebrew刚好把这块空白补上了。
1.2 Homebrew和App Store、dmg安装包的区别
很多人会问,为什么不用App Store?不是挺好的吗?这里面的差异比较大,我用一张表说明:
| 对比项 | Homebrew | App Store | dmg/pkg |
|---|---|---|---|
| 安装范围 | 命令行工具、库、GUI软件都能装 | 只能装App Store审核过的应用 | 一包一装,来源分散 |
| 依赖处理 | 自动处理依赖 | 自带运行库,较少关心依赖 | 经常要求你手动装依赖 |
| 更新方式 | brew upgrade一条命令全部更新 | 系统提示更新 | 需要重新下载安装包 |
| 卸载方式 | brew uninstall,干净彻底 | 拖废纸篓,但仍可能有残留 | 拖废纸篓,手动清残留 |
| 是否自动配置环境变量 | 多数公式会提示,部分自动配置 | 不需要环境变量 | 经常需要手动配置 |
从表格能看出来,Homebrew的命令行风格和Linux的apt、yum很像。它不是在跟App Store抢饭碗,而是换了种玩法:把软件安装变成可脚本化、可复现的操作。举个例子,你新买一台Mac,只需要在自己的脚本里写上十几条brew命令,就能把开发环境重建出来,这在dmg时代几乎不可能。
1.3 Homebrew在macOS系统中的角色定位
Homebrew安装后的核心目录,在Intel处理器的Mac上是/usr/local,在Apple Silicon上则是/opt/homebrew。这个区别很重要,因为后面所有PATH配置、权限问题都跟它相关。它并不是像大多数软件一样把自己装进/Applications,而是把自己作为一套独立的软件树,管理在一个自定义前缀目录下。
这种设计有个明显的好处:不污染系统自带的/usr/bin。你可以放心安装新版本的Python、Git、OpenJDK,而不必担心和macOS系统自带的旧版本冲突。Homebrew内部通过“Cellar”目录存储所有安装的软件版本,然后通过软链接把当前版本暴露到/usr/local/bin或/opt/homebrew/bin。这些概念刚开始不用记太死,但知道它们能帮你理解为什么有时候which python3指向Homebrew目录,有时候又指向系统目录。
2. 安装与卸载:从零开始配置Homebrew环境
2.1 安装前的检查和必要组件
安装Homebrew前,先确认系统满足最低要求。以当前主流的Homebrew 4.x为例,它要求macOS 11 Big Sur及以上。如果你的系统比这还老,后面有一节专门讲旧系统怎么办,这里先按新系统来。
然后需要确保macOS的Command Line Tools已经装好。这个组件包含了编译软件必需的clang、git、make等一系列工具,也是Homebrew安装时经常依赖的东西。你可以在终端里执行:
xcode-select --install如果弹窗说已经安装,那就直接进行下一步。如果提示找不到,装完再来。很多新手在这步会卡很久,其实不用启动完整版Xcode,命令行工具只有几百MB,比十几GB的Xcode轻量多了。
2.2 官方安装脚本与国内镜像加速
确认Command Line Tools就绪后,用官方脚本安装即可:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"这个脚本会一路检查系统、创建目录、下载Homebrew仓库。但国内网络直连GitHub经常很慢,如果你看到脚本长时间卡在Updating Homebrew,或者curl报错,不要傻等。更常用的方案是设置国内镜像环境变量后重新跑安装脚本。以清华镜像为例,在执行安装脚本前先输入:
export HOMEBREW_API_DOMAIN="https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles/api" export HOMEBREW_BOTTLE_DOMAIN="https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles" export HOMEBREW_BREW_GIT_REMOTE="https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git" export HOMEBREW_CORE_GIT_REMOTE="https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-core.git"然后再执行官方安装脚本。同样逻辑,中科大、阿里云的镜像也能用,只是地址不同。这样安装完成后,后续的brew install下载预编译包时,默认会走镜像源,速度会明显提升。别一上来就怀疑是电脑问题,90%的安装失败都是网络连接GitHub不稳定导致的。
2.3 验证安装与后续配置
安装完成后,先执行brew --version确认能输出版本号。在Apple Silicon的Mac上,脚本通常会在最后提示你需要把Homebrew目录加入PATH。常见做法是把下面这行写入~/.zshrc:
export PATH="/opt/homebrew/bin:$PATH"写入后重新加载一下配置文件,再执行which brew,如果输出/opt/homebrew/bin/brew,说明环境变量生效了。接下来建议跑一次brew doctor,它会检查系统设置、依赖库版本、目录权限等有没有问题。不要害怕那个长长的输出,你只需要关注标红区域,通常给出的处理建议也很直白,照着执行就行。
2.4 卸载Homebrew和清理残留
有些时候你需要彻底卸载Homebrew,或者安装过程坏到不行想从头再来。官方其实提供了一个卸载脚本:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/uninstall.sh)"它会列出将要删除的内容并询问确认。但如果之前手动改过目录结构,或者曾经用sudo操作过,脚本可能漏掉部分残留。我实际遇到过“卸载完再安装时提示目录非空”的情况,主要残留位置集中在以下几个地方:
/usr/local/Cellar(Intel Mac)或/opt/homebrew/Cellar/usr/local/Homebrew或/opt/homebrew~/Library/Caches/Homebrew~/Library/Logs/Homebrew/Library/Homebrew
卸载前建议先把brew list导出成清单,方便以后重装。清理时务必小心,不要误删其他软件的数据。如果你只卸载某一个软件而不是整个Homebrew,用brew uninstall --force就行,不需要碰这些目录。
3. 核心命令速查:能解决90%日常需求的基本操作
3.1 安装、卸载与清理软件的完整闭环
日常用得最多的就是brew install。安装命令行工具直接写:
brew install wget brew install openjdk@17 brew install maven如果软件有多个版本,可以在名称后加@版本号,比如openjdk@11、python@3.9。需要装图形界面软件时,用--cask参数:
brew install --cask google-chrome brew install --cask visual-studio-code brew install --cask wechat这个--cask是Homebrew管理GUI应用的子模块,安装时会从官方渠道下载dmg或pkg并自动完成挂载和安装,效果相当于帮你省掉了“下载、打开、拖拽、退出”这一整套手动流程。有些老教程还会写brew cask install,但在Homebrew 2.6之后,cask命令被并入brew install --cask,老写法已经过时了。
卸载和清理要养成配套习惯:
brew uninstall wget brew uninstall --cask google-chrome brew autoremove brew cleanupbrew autoremove会删除不再需要的依赖,比如你卸载了一个软件,它当年自动装好的几十个依赖库如果没有被别的东西引用,就会被清掉。brew cleanup则是清理旧版本安装包和缓存。我把这三个命令包装成一个习惯:卸载软件后先autoremove,再cleanup,这样Homebrew的存储占用能长期保持在一个健康水平。
3.2 查询与查找:搜索、信息、依赖关系
装之前先搜索一下,能避免不少坑:
brew search maven brew info mysql brew info --cask google-chromebrew info显示的信息很有价值,包括当前稳定版本、依赖关系、安装后需要做什么配置(caveats)以及是否为keg-only。keg-only这个词见得多,含义是“这个软件不会主动链接到PATH里”,比如OpenJDK和Python都经常标记为keg-only,原因是怕和系统自带版本冲突。遇到这种提示,要么手动添加软链接,要么按提示执行额外的配置命令。
如果想看某个公式的依赖树,可以执行:
brew deps --tree ffmpeg它会输出一棵依赖树,让你知道安装这个软件会牵连多少库。另一个实用的是brew uses --installed git,能反查已安装的哪些软件依赖了Git。这些查询类命令不会修改系统,可以放心多试。
3.3 更新、升级与版本管理
Homebrew本身和它管理的软件是两套升级逻辑。升级Homebrew本身用:
brew update更新软件列表和可用版本。升级某个软件用:
brew upgrade wget想一次升级所有已装软件,直接brew upgrade。但在准备全量升级前,最好先看一眼有哪些可更新:
brew outdated这个命令会列出所有有新版本的软件。我个人的习惯是先跑brew outdated,再决定是全部升级还是只挑几个重点升级。原因很简单:有些软件升级后配置不一定兼容,比如某个自定义的配置文件路径变了,或者依赖的大版本变了。如果你的工作环境不能出一点差池,可以用brew pin锁定版本:
brew pin mysql brew unpin mysql锁定后,brew upgrade会跳过被pin的软件。这是团队环境或生产环境里非常实用的功能,小项目单人开发可能用不上,但值得知道。
3.4 服务管理:让后台软件开机自启
源码包安装的软件里,有一部分是以守护进程形式运行的,比如MySQL、Redis、Nginx、PostgreSQL。以前你需要手动去配置launchd plist文件,Homebrew提供了一个更友好的封装:brew services。
先看当前所有服务状态:
brew services list启动某个服务并设置开机自启:
brew services start mysql停止服务并取消开机自启,直接执行brew services stop mysql。如果想临时跑一次,不想注册开机项,可以使用brew services run mysql。这三个命令的区别很多新手容易绕晕,实际用下来记一条经验:日常开发用start/stop就够了,如果只是临时测试某个服务,尽量别用start,免得电脑开机自动拉起一堆进程。
有一类服务不适合用brew services管理,比如你自己编译的一些一次性脚本服务,或者需要自定义复杂启动参数的进程。这时更合适的是手动写launchd plist。brew services适合那些安装后“开了就不管”的常见服务。
3.5 查看环境状态:doctor、config、list
当Homebrew行为异常时,第一反应不是删库重装,而是先诊断:
brew doctor它会检查常见问题,比如目录权限不对、链接失效、重复安装等。很多时候输出的建议就是一行命令,执行完就解决了。另一条实用命令是:
brew config它会列出Homebrew版本、macOS版本、CPU架构、HOMEBREW_* 环境变量等信息。配合国内镜像排查时,我经常先跑它确认是否真的走了镜像源,避免环境变量没生效还白折腾。
查看装了哪些东西:
brew list brew list --cask brew list --formula这里--formula和--cask区分了命令行软件和图形软件。如果你的机器上装了上百个软件,还可以用brew leaves查看“直接安装的顶层软件”,排除掉依赖项。这个命令在统计环境清单时特别好用。
4. 常见问题与排查技巧实录
4.1 安装脚本一直卡住或报错,多半是网络问题
先看一个非常典型的错误:执行官方安装脚本后,长时间停留在Updating Homebrew...,然后curl断开或者git clone失败。这不一定是Homebrew坏了,而是在下载GitHub上的仓库时网络不稳定。最常见的解决方案是像我前面提到的,先设置国内镜像环境变量,再重装。
另外,安装某些软件时可能出现下载预编译包(bottle)失败的情况。Homebrew的bottle默认从ghcr.io下载,速度同样不稳定。配置了HOMEBREW_BOTTLE_DOMAIN后,安装包会从镜像拉取。这一步做完,绝大多数“下载失败”问题都会明显缓解。
还有一个小细节:如果在终端里使用了一些网络转发工具,有时反而会因为SSL证书问题导致curl失败。这里不讨论具体工具,只说一句:尽量让Homebrew走系统默认网络和镜像源,问题最少。
4.2 brew update 慢和“不能更新”报错
很多人会遇到brew update卡住,以及下面这种报错:
Error: fatal: not in a git directory这种通常是因为本地Homebrew仓库的git remote源指向了GitHub,而更新时拉不下来。解决办法是直接把remote切到镜像:
git -C "$(brew --repo)" remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git git -C "$(brew --repo homebrew/core)" remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-core.git git -C "$(brew --repo homebrew/cask)" remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-cask.git针对不同安装路径和版本,brew --repo homebrew/core可能输出不同的目录,不过命令本身会自适应,直接执行就行。切换完再brew update,基本能恢复正常。记住,这不是Homebrew本身的bug,纯粹是网络环境导致的git同步问题。
4.3 macOS版本兼容性问题:Homebrew 4.0 不再支持 10.15
这几年关注Homebrew的人应该都知道,官方升级策略越来越明确。Homebrew 4.x把最低系统要求提到了macOS 11 Big Sur,也就是说Catalina(10.15)及更早的机器没法再用新版Homebrew更新软件。如果你还在用旧系统,但有不想升级的苦衷,能走的路大致有三条:
第一条,安装旧版Homebrew。Homebrew 2.x时代还是支持10.15的。我见过有人在旧Mac上把仓库切到2.x分支继续用,大概操作是进入$(brew --repo)目录后执行git checkout到指定版本,但后续新增软件包不再保证兼容,属于“能用但别指望长期维护”的状态。
第二条,直接下载官方独立安装包或dmg来替换特定软件,绕开Homebrew。比如某些需要特定版本的数据库,直接从官网下载tar.gz包自己配置,也能正常工作。
第三条,升级系统到受支持的版本。这个最省心,但要考虑你的老设备跑不跑得动新系统。兼容性问题没有完美解,只能根据自己这台机器的使用定位来选择。我个人的看法是:如果这台机器还有重要开发需求,尽早规划升级;如果只是做轻量办公,旧版Homebrew凑合用也问题不大。
4.4 权限问题与 command not found
新用户最常遇到的另一个问题是刚装完Homebrew,执行brew却提示zsh: command not found: brew。原因一般是两个:壳的PATH变量里没有Homebrew目录,或者安装时用了sudo导致目录属主变成了root。
如果是PATH问题,按前面说的把export PATH="/opt/homebrew/bin:$PATH"写入~/.zshrc或~/.bash_profile即可。如果是权限问题,需要把目录归还给当前用户:
sudo chown -R "$(whoami)":admin /opt/homebrew这个命令同样适用于Intel Mac下的/usr/local。我特别不建议在执行brew install时加上sudo。Homebrew的设计初衷就是“不需要root就能管理软件”,装到系统目录之外的前缀里。一旦用了sudo,它会把部分文件写入到root所有,后续每次操作都可能出现权限报错,处理起来非常麻烦。
4.5 残留问题:升级失败后目录和进程清理
Homebrew升级版本后,旧的目录结构可能残留。最常见的是以前Homebrew 1.x或2.x留下的~/.homebrew、/usr/local下的一部分旧目录和新版本冲突。比如你重装Homebrew后,系统提示某个Cellar子目录“已存在且非空”,这时不要暴力删除,先看里面有没有你在用的小项目或配置数据。
更常见的残留是软件的旧版本。比如python@3.9更新到了3.9.5,旧的3.9.4目录仍留在Cellar里。用brew cleanup能清除旧版,但如果某个软件被标记为“keg-only且没有其他版本依赖”,autoremove也可能把它连带删掉。所以,每次批量清理前,我习惯先跑brew list记录当前清单,出问题还能知道少了什么。
5. 几年实践经验总结:Homebrew怎么用才舒服
5.1 我的几个使用习惯
用Homebrew这几年,我慢慢形成了一套相对固定的工作流。首先是安装命令习惯性写成一行,把软件来源和用途写在注释里,方便以后追溯。比如:
# 开发基础 brew install git brew install openjdk@17 brew install maven # 日常工具 brew install --cask visual-studio-code brew install --cask wechat其次是「分组安装」。我会把开发环境、日常办公、媒体处理等不同场景的命令分组记录,配合brew bundle还能自动生成 Brewfile,当前机器上装了什么一目了然。要迁移到新机器时,只需要把Brewfile带过去执行一遍,基本就恢复了七八成开发环境。
第三是定期体检。我基本上每隔一两周跑一次brew doctor、brew outdated、brew cleanup三个命令。这个习惯帮我规避了好几次“因为某天突然升级导致环境崩掉”的风险。大版本升级前,我会先看看brew info里有没有特别提示,比如配置文件迁移,再决定是否升级。
5.2 值得一提的周边扩展:Brewfile、mas与版本管理工具
Homebrew本身能力已经很强,但更舒服的玩法是搭配周边工具。brew bundle是官方自带的功能,通过brew bundle dump把所有已装软件导出成Brewfile,再用brew bundle install一键恢复。我还在Brewfile里用tap和mas管理更细粒度需求,mas可以从Mac App Store安装部分应用。比如说,你可以这样:
brew install mas mas list mas search "Xcode" mas install 497799835用法是先通过mas search找到应用ID,然后安装。如果某天brew list看到的软件不能满足你说“我要整套环境”,Brewfile就是解决方案。另外,多语言版本管理方面,我会把Homebrew和mise搭配使用,用brew安装工具链本体,用mise管理同一语言的不同版本,避免在系统层面装太多重复的东西。
5.3 给新手朋友的实在建议
最后说点带情绪的经验。Homebrew确实强大,但它不是万能的。它擅长的是“开源工具、命令行软件、开发者库”的安装管理,对于某些商业软件、跨系统安装包,还是老老实实去官网下载更好。别听别人说“所有软件都能用brew装”,就去强行brew install,有些软件的官网更负责任,更新更快。
另外,安装时多看一眼输出的caveats信息。很多新手装完直接关终端,之后再为“为什么python3指向的不是我装的版本”这种问题折腾半天。其实Homebrew通常已经把提示写在安装日志里了,照着做就行。最后一条建议来自我的惯性翻车经验:对brew upgrade保持敬畏,生产环境的机器别在没备份的情况下盲目全量升级。把brew pin用起来,锁住关键软件,你就能安心享受Homebrew带来的便利。