在 mac 上折腾开发环境这件事,每个人的起点都差不多:下载一个 dmg,拖进 Applications,遇到命令行工具就跑官网找 pkg,装完一个还有下一个。等手上同时有三五个项目要跑,Python 多个版本、JDK 多个版本、数据库、命令行小工具全堆在一起的时候,靠手动下载安装包管理这套东西会迅速失控——你记不住哪个版本装在哪,卸载的时候也删不干净,换台机器又要重来一遍。Homebrew 就是被这个问题逼出来的产物。它是 mac 上目前使用最广的包管理器,一行命令就能把软件装好、升级、卸载,顺带把依赖关系一起处理掉。这篇内容我打算把自己在几台不同芯片的 mac 上反复装 Homebrew 的过程完整写一遍,从它解决什么问题、装之前要确认哪些环境信息,到安装、环境变量配置,再到最常见的几类报错和残留清理,尽量把每一步“为什么这么做”也讲清楚。刚拿到 mac 的新手照着走一遍就能装好;已经装过但经常踩坑的人,后面排查和清理那几节应该更有用。
1. Homebrew 到底是什么,它解决了哪些真实痛点
1.1 一句话讲清它的定位
Homebrew 是一个跑在 macOS 上的包管理器,你可以把它理解成 mac 版的“应用商店加依赖管家”,只不过它主要服务于命令行工具和开发环境,而不是双击就能用的图形软件。它的核心工作只有三件事:知道某个软件在哪、把它下载并安装到正确的位置、记录它依赖了哪些别的东西并一起处理。你可能听过 npm、pip、apt 这些名字,Homebrew 在 mac 上扮演的角色,和 apt 在 Debian 系发行版里的角色基本一致,区别是它同时兼顾了命令行工具和图形应用两种安装形态,这一点后面讲 formula 和 cask 的时候会展开。
很多人第一次接触它是因为装 Git 或者 Python,装完之后发现连 ffmpeg、wget、jq 这类小工具也能一行搞定,然后慢慢就把整台机器的软件管理都交给它了。这不是偶然,是它的设计目标决定的:把软件的分发、版本记录、依赖解析全部收拢到一个统一的命令行入口。
1.2 手动装和用它装,差别到底在哪
手动装软件的流程大家都熟:打开浏览器,找到官网,挑和自己芯片匹配的安装包,下载、拖拽、输入密码。这套流程装一两个软件没问题,问题出在规模上。当你需要在多台机器上复现同一套环境,或者需要回退某个工具的版本,手工操作的成本会急剧上升,而且没法复用。Homebrew 把这些动作压缩成一行命令,命令本身可以写进脚本、写进项目文档、发给同事,别人照着跑一遍就能得到基本相同的结果,这在团队协作里的价值比省那几分钟下载时间大得多。
更关键的是依赖管理。很多命令行工具不是独立存在的,它背后可能依赖某个库、某个运行时的特定版本。手动安装时这些依赖得你自己一个个去查、去装,顺序错了还会报错,报错信息还未必告诉你缺的是哪个。Homebrew 会自动算出依赖树,按正确的顺序装好,卸载时也会把不再被引用的依赖标记出来让你清理。这一层“记账”能力,才是它真正难被替代的地方。
1.3 判断自己是不是真的需要装它
不是所有人都需要 Homebrew。如果你只是用 mac 看视频、写文档、剪片子,从 App Store 和官网下软件完全够用,装个包管理器反而是多一层维护负担。但如果你符合下面任意一条,我建议尽早装上:
- 需要在终端里使用 git、python、node、java、maven 这类开发工具;
- 需要同时维护多个版本的同一款工具,比如 JDK 8 和 JDK 17 之间来回切;
- 需要把环境配置步骤写下来交给别人复现;
- 喜欢用命令行解决重复劳动,比如批量转换格式、批量处理文件;
- 开发中要频繁试各种小工具,不想每次都跑官网找安装包。
这几类场景下,Homebrew 省下来的时间是以小时计的,而且它把“软件装在哪、版本是什么”这件事变得可查询、可追溯,出问题时排查成本会低很多。
2. 动手之前,先把这几个前提条件搞清楚
2.1 芯片架构直接决定了安装路径
这是新手最容易懵的一点。mac 分 Apple Silicon(M 系列芯片)和 Intel 芯片两大类,Homebrew 在这两类机器上的默认安装目录是不一样的:Apple Silicon 装在/opt/homebrew,Intel 装在/usr/local。为什么会有这个区别?因为 Apple Silicon 上的/usr/local已经承担了别的职责,而且 Apple 对系统目录的写保护策略不同,所以 Homebrew 团队把 M 系列的默认前缀改成了/opt/homebrew,避免和系统以及其它软件打架。
这个差异带来的直接后果是:所有配置命令里的路径都要跟着变。你在网上抄到一段配置,如果不对应自己的芯片,就会报“command not found”或者路径不存在的错误。想确认自己的架构很简单,打开终端执行:
uname -m输出arm64就是 Apple Silicon,输出x86_64就是 Intel。也可以直接用arch命令看。记住这个结果,后面写环境变量时会反复用到。
2.2 Command Line Tools 和 Xcode 的关系
Homebrew 的很多操作背后要调用编译器和相关命令行工具,所以它依赖 macOS 的 Command Line Tools(简称 CLT)。如果你机器上已经装了完整的 Xcode,那 CLT 一般也一并装好了;如果没装,安装 Homebrew 的过程中脚本会提示你先装 CLT。
单独安装 CLT 的命令是:
xcode-select --install执行后会弹出一个系统对话框,点确认,然后等下载安装完成。这里有个常见的坑:网络状况不好的时候,这个下载会卡住或者超时,而且它是在系统层面弹窗,终端里看不到进度,很多人以为死机了。遇到这种情况,先去“系统设置”里看看是不是有个软件更新在挂着,或者换个时间段再试。另外,xcode-select -p可以查看当前选中的开发者工具路径,如果这个命令报错,说明 CLT 没装好或者路径指向有问题,后面安装 Homebrew 一定会失败。
2.3 网络环境会直接影响安装成功率
Homebrew 的安装脚本和后续的软件源都托管在境外服务器上,脚本本身只有几十 KB,但后续拉取索引和下载软件包时数据量会大得多。拉取脚本这一步如果一直转圈不出结果,通常就是网络通路不畅。我的建议是做好两手准备:先按官方方式试一次,如果卡在拉取脚本或者brew update迟迟不动,就换成国内学术机构和云厂商公开提供的开源软件镜像服务,这类镜像站是可以直接访问的,配置方法在 3.3 节会详细讲。
这里提前说明一个概念:Homebrew 的镜像配置本质上是把 git 远程仓库地址替换掉,让它从另一个公开的服务器拉数据,这属于常规的软件源配置操作,和系统层面的任何网络设置无关,只是换了个下载地址。理解这一点,后面看配置文件就不会觉得绕。
3. 安装实操:从一行命令到验证通过
3.1 官方脚本安装的完整过程
确认好架构和 CLT 之后,安装本身其实只有一步。官方给出的命令是:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"这条命令拆开看是三部分:curl -fsSL负责把安装脚本下载下来,-f表示遇到 HTTP 错误就失败而不是输出错误页面,-s是静默模式,-S是在出错时显示错误,-L是跟随重定向;/bin/bash -c表示用系统自带的 bash 执行下载到的内容。为什么用系统自带的 bash 而不是你现在用的 shell?因为安装脚本需要在各种环境下都能跑起来,系统 bash 是最保守的选择。
执行后脚本会先自我介绍,然后告诉你它准备做什么,并等待你按回车确认。这一步建议认真看一眼输出,它会列出将要创建的目录。确认后会开始下载,过程中可能需要输入一次开机密码,这是为了给/opt/homebrew或者/usr/local相关目录授权,属于正常行为,不是脚本在偷权限。
安装完成后,脚本通常会打印一段提示,告诉你“接下来需要把 brew 加入 PATH”,并给出对应的命令。很多人就是忽略了这段提示,装完发现输入brew提示找不到命令,以为装失败了,其实只是环境变量没配。
3.2 环境变量到底该写进哪个文件
macOS 从 Catalina 开始默认 shell 换成了 zsh,所以配置文件是~/.zprofile或者~/.zshrc,这两个的区别是加载时机:~/.zprofile在登录 shell 启动时读取一次,~/.zshrc在每次打开交互式 shell 时读取。Homebrew 官方推荐写进~/.zprofile,因为环境变量只需要设置一次,没必要每次开终端都执行。
Apple Silicon 机器执行:
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile eval "$(/opt/homebrew/bin/brew shellenv)"Intel 机器把路径换成/usr/local/bin/brew:
echo 'eval "$(/usr/local/bin/brew shellenv)"' >> ~/.zprofile eval "$(/usr/local/bin/brew shellenv)"这里用brew shellenv而不是手动写export PATH=...是有讲究的。brew shellenv会把 brew 需要的所有环境变量一次性输出,包括 PATH、MANPATH、INFOPATH 以及一些内部变量。手动写 PATH 只能解决命令找不到的问题,但手册页路径、补全脚本这些不会生效。用官方提供的方式,以后 Homebrew 自身调整了变量,你也不用改配置。
写完配置后,新开一个终端窗口,或者执行source ~/.zprofile,让配置生效。
3.3 换源配置与路径冲突的处理
如果你在拉取索引或者安装软件时明显感觉慢,可以换成公开的开源软件镜像服务。做法分两步:先让安装脚本从镜像站拉,再让后续的 git 仓库指向镜像。
对于已经装好的 Homebrew,可以通过环境变量指定镜像地址,把下面几行加到~/.zprofile里:
export HOMEBREW_API_DOMAIN="镜像站提供的 API 地址" export HOMEBREW_BOTTLE_DOMAIN="镜像站提供的二进制包地址" export HOMEBREW_BREW_GIT_REMOTE="镜像站提供的 brew 仓库地址" export HOMEBREW_CORE_GIT_REMOTE="镜像站提供的 core 仓库地址"具体地址以你选择的镜像站最新文档为准,这类站点会随版本调整路径,写死在文章里很容易过期。除了环境变量,还可以直接改 git 远程地址:
git -C "$(brew --repo)" remote set-url origin 镜像仓库地址 git -C "$(brew --repo homebrew/core)" remote set-url origin 镜像仓库地址 git -C "$(brew --repo homebrew/cask)" remote set-url origin 镜像仓库地址改完之后执行brew update验证能不能正常拉取。这里要提醒一句:镜像只解决“下载地址”的问题,不改软件本身的版本策略,所以不必担心装到的是旧版本,索引同步通常有几分钟到几小时的延迟,日常使用完全够。同时建议一次性把配置写全,只改 brew 仓库不改 core 仓库,会出现拉索引还是慢的情况,这是最常见的“配了没用”的原因。
3.4 怎么确认真的装好了
判断安装是否成功,不要只看命令有没有报错,按下面几步走一遍更靠谱。
第一步,查版本:
brew --version能正常输出 Homebrew 版本号和最后一次更新的 git 提交,说明主程序可用。
第二步,查安装前缀:
brew --prefixApple Silicon 应该输出/opt/homebrew,Intel 输出/usr/local。如果这里输出的是别的位置,或者提示路径不存在,说明安装过程有问题。
第三步,做一次自检:
brew doctor这个命令会检查你的环境有没有明显毛病,比如 PATH 顺序不对、有重复安装、权限异常等。它输出的 warning 不一定都是问题,但每一条都值得读一遍。我见过最常见的一条是“你的 PATH 里/usr/local/bin排在/usr/bin前面”,对于 Intel 机器来说这往往是正常的,看到不用慌,结合自己的架构判断就行。
第四步,装个小东西试试:
brew install wget能顺利下载并安装,才算真正跑通。如果这一步失败,问题基本集中在网络源或者权限上,直接跳到第 4 节。
提示:安装完成后不要急着装一堆软件。先用
brew install装一个小的命令行工具验证通路,确认没问题再批量操作,能省掉大量排查时间。
4. 报错排查实录:我遇到过的几类典型问题
4.1 xcode-select 相关的报错
这是安装阶段最高频的报错,典型输出是“xcode-select: error: command line tools are already installed, but the software is not available at the expected location”或者直接提示 CLT 未安装。前一种情况通常发生在你手动删过 CLT 目录,或者系统升级后路径失配。处理方式是先查看当前路径:
xcode-select -p如果输出的路径在文件系统里不存在,就需要重置。普通用户删不掉/Library/Developer/CommandLineTools这个目录,得先取得权限再删除,然后重新执行xcode-select --install。删除系统目录属于高风险操作,务必确认路径没写错再动手,或者在图形界面里确认该目录已损坏后再处理。
还有一种情况是 CLT 装了但系统里存在多个版本,xcode-select指向了错误的那个。这时候用sudo xcode-select --switch切换到包含 CLT 的路径即可。判断“包含”的方法是看那个目录下有没有usr/bin/clang这类文件存在。
4.2 下载中断与超时
安装脚本执行到一半卡住,或者brew update长时间停在“Fetching”上,是第二类高频问题。原因基本是网络通路不稳。处理思路按成本从低到高排:
- 重新执行一次。临时的通路抖动占相当比例,重试就能过。
- 确认代理相关软件、企业安全客户端没有拦截。很多人在公司电脑上装失败,是因为本机装了网络管控类的客户端,它会对系统级请求做检查,导致 git 访问被中断。这类情况下临时关闭相关客户端再试,通常就通了。
- 换用镜像源,按 3.3 节的配置走一遍。
- 检查系统时间是否准确。这个坑比较隐蔽,系统时间和服务器差异过大时,TLS 握手会失败,表现出来就是连接被拒绝或者证书错误。在“系统设置”里打开自动设置日期与时间即可。
注意:不要为了装个包管理器去改动系统底层的网络配置,那样带来的后续问题远比省下的时间多。先换源,再考虑其它。
4.3 Intel mac 装不上的几种情况
老 Intel 机器上装 Homebrew 这两年确实更容易出问题,我遇到过的主要有三类。
第一类是系统版本太老。Homebrew 官方对 macOS 版本有最低要求,如果你的系统停留在十年前的大版本上,安装脚本会直接拒绝执行并提示版本不支持。这种情况要么升级系统,要么使用第三方维护的旧版本分支,但后者意味着拿不到安全更新,需要自己权衡。
第二类是 Rosetta 引起的路径混乱。在 Apple Silicon 上通过 Rosetta 跑 x86 程序时,/usr/local会被“映射”到一个特殊位置;而 Intel 机器上/usr/local是真实目录。如果有人把从 M 系列机器上抄来的配置直接用在 Intel 机器上,就会出现“命令能跑但装的软件找不到”的怪现象。解决办法是老老实实确认uname -m的输出,路径老老实实跟着架构走。
第三类是磁盘空间和权限。/usr/local下如果存在历史遗留的、属主不是当前用户的目录,Homebrew 安装时会因为无法写入而失败。这时候不要直接chown -R整个/usr/local,那会影响到其它软件。更稳的做法是先把残留的旧目录改名备份,再重新安装。
4.4 权限与目录归属问题
brew doctor报权限问题时,先看清楚它指的是哪个目录。如果是 Homebrew 自己创建的目录,比如/opt/homebrew,用sudo chown -R $(whoami) /opt/homebrew修正是合理的。如果是/usr/local下的其它软件目录,就不要动,那些属于别的安装方式,改了会引发更难查的问题。
还有一个很多人忽略的点:不要把brew命令和sudo brew混用。Homebrew 在设计上就明确不允许以 root 身份运行,你用sudo brew install大概率会得到一条明确的拒绝提示。它这样做是为了保证安装出来的文件属主一致,避免以后升级时权限冲突。同理,安装脚本里出现一次密码输入是正常的,那是系统授权步骤,不是 Homebrew 自己在要 root。
4.5 常见问题速查表
| 现象 | 大概率原因 | 处理方向 |
|---|---|---|
| 输入 brew 提示 command not found | 环境变量没配或配错文件 | 按架构写入~/.zprofile并重新加载 |
| 安装脚本卡在拉取阶段 | 网络通路不通 | 重试、换镜像源、检查网络管控客户端 |
| xcode-select 报路径不存在 | CLT 缺失或指向错误 | 重装 CLT 或切换路径 |
| brew doctor 报 PATH 顺序问题 | 不同架构的配置混用 | 核对uname -m与 PATH 内容 |
| 安装时提示权限不足 | 目标目录属主异常 | 只修正 Homebrew 自己创建的目录 |
| brew update 报证书错误 | 系统时间不准 | 打开自动设置时间 |
| 装完找不到刚装的命令 | 软件装到了另一个前缀目录 | 用brew --prefix核对并统一 PATH |
| 升级后命令行为异常 | 旧版本残留或链接未刷新 | 执行brew cleanup与brew link |
5. 装好之后:日常高频操作与配套工具
5.1 必须记住的几条命令
装完只是开始,真正每天用的是下面这些:
brew search 关键词 # 搜索软件 brew info 软件名 # 查看版本、依赖、来源 brew install 软件名 # 安装 brew uninstall 软件名 # 卸载 brew list # 列出已装软件 brew upgrade # 升级全部 brew upgrade 软件名 # 升级指定软件 brew outdated # 只看哪些需要升级 brew cleanup # 清理旧版本缓存 brew doctor # 环境自检这里面brew info是被低估最多的命令。它会告诉你这个软件依赖什么、装完之后有哪些文件、有没有可选的安装参数。装之前先看一眼,能避免很多“装完才发现不是我想要的版本”的尴尬。brew outdated也值得养成习惯,每周看一眼,比无脑全量升级更可控,尤其是生产环境里跑的东西,升级前最好先看变更说明。
5.2 formula 和 cask 的区别
Homebrew 里有两个概念容易混:formula 和 cask。formula 指的是从源码或二进制包构建出来的命令行工具和库,比如 wget、jq、ffmpeg;cask 指的是打包好的图形应用,比如浏览器、编辑器、截图工具这类平时拖进 Applications 的东西。安装 cask 要显式加参数:
brew install --cask 软件名用 cask 装图形软件的好处是升级和卸载也能交给它统一管理,卸载时不会留一堆配置散落在系统里。但要注意,cask 装的软件有时不会出现在启动台里,需要手动从 Applications 里找一下,或者用brew list --cask确认装没装上。
5.3 开发环境常用软件怎么装
搭建开发环境时,下面这些基本是一套标准动作,按需取用:
- 版本控制:
brew install git,装完记得配置用户名和邮箱,否则提交记录里是一串无意义的机器名。 - Java 环境:
brew install openjdk@8或更高版本,装完要按提示把JAVA_HOME指向对应路径,多个版本共存时用软链接切换。 - 构建工具:
brew install maven和brew install gradle,装完执行mvn -v确认能识别到正确的 JDK。 - Python:
brew install python@3.12这类带版本号的写法更可控,系统自带的 Python 不要动,它是系统组件。 - 容器:
brew install --cask docker,装完首次启动要授权,之后命令行里的 docker 才可用。 - 数据库客户端:
brew install --cask方式装图形客户端,或者用命令行版本,看你偏好。 - 命令行 AI 辅助工具:这类工具通常通过 npm 全局安装,前提是先
brew install node,装好后用npm install -g装对应包,注意全局包的 PATH 也要配好。
一次性把这些装完的好处是,你的环境配置可以写成一个脚本,换机器时直接跑。我自己的做法是维护一个setup.sh,里面按顺序列出所有brew install命令,新机器上跑十分钟就能恢复到熟悉的状态。
5.4 服务管理与后台进程
有些软件装完需要常驻后台,比如数据库、缓存服务。Homebrew 提供了 services 子命令来管理:
brew services list # 查看所有服务状态 brew services start 服务名 # 启动并设置开机自启 brew services run 服务名 # 只启动,不设自启 brew services stop 服务名 # 停止 brew services restart 服务名 # 重启用 services 管理比手动写启动脚本省事,但它默认以当前用户身份运行,日志位置也由 Homebrew 决定。如果服务起不来,先去对应软件自己的日志目录里找线索,而不是反复重启。
5.5 定期维护别偷懒
Homebrew 用久了会堆积旧版本和缓存,占用几个 GB 空间很常见。定期执行brew cleanup可以清掉不再需要的旧版本;加-n参数是预演,只显示会删什么,不实际执行,确认无误再去掉参数。brew autoremove会清理不再被任何软件依赖的孤立包,这两条配合使用,能明显瘦身。
还有一点,很多人关心“系统数据”占用为什么越来越大,其中一部分就是各类包管理器的缓存。清缓存前先用brew cleanup -n看一眼量级,避免误删正在使用的版本。
6. 卸载与残留清理:重装前一定要做的事
6.1 标准卸载流程
如果只是想把 Homebrew 干净移除,官方提供了卸载脚本:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/uninstall.sh)"执行过程会提示你确认,并且会列出将要删除的目录。这时候建议仔细看一遍,确认里面没有你自己手动放进去的文件。脚本默认会问你要不要一起删除整个安装目录,如果只是想重置环境,可以保留目录只清软件,然后再手动处理。这里有个小技巧:先把脚本下载到本地存成文件,看一眼内容再执行,比直接管道执行更稳妥,尤其是网络环境不理想的机器,避免执行到一半中断留下半成品状态。
6.2 手动清残留目录
脚本跑完之后,通常还会剩下一些缓存和日志。需要检查的位置包括:
~/Library/Caches/Homebrew:下载缓存,通常最大~/Library/Logs/Homebrew:安装日志/Library/Caches/Homebrew:系统级缓存~/Library/Preferences下与具体软件相关的配置文件~/.zprofile或~/.zshrc里那几行环境变量,记得一并删掉
环境变量那一行特别容易被忘。删了程序不删配置,下次重装时旧配置和新的混在一起,PATH 里出现两条指向不同路径的 brew,表现出来就是“命令能跑但版本不对”,排查起来非常折磨。
6.3 重装前的检查清单
准备重装之前,按这个顺序过一遍,能避免绝大多数重复踩坑:
- 确认
uname -m的输出,路径按架构写。 - 确认
xcode-select -p指向有效目录。 - 检查
~/.zprofile里没有旧的 PATH 配置残留。 - 确认
/opt/homebrew或/usr/local/Homebrew已经没有残留目录。 - 确认磁盘剩余空间足够,索引和缓存通常要几百 MB 到数 GB。
- 想清楚是否要用镜像源,要用就一次性配全。
我之前有台机器就是因为第 4 条没做,重装后新旧两套目录同时存在,brew doctor报了一堆警告,最后花的时间比第一次装还多。从那之后我养成了习惯:卸载完先手动确认目录真的空了,再开始装。
我个人在实际操作中的体会是,Homebrew 这类工具真正的门槛不在安装那一步,而在环境变量的准确性和后续的维护习惯。安装脚本本身容错性做得不错,大多数失败都能从“架构对不对、CLT 全不全、网络通不通”这三个方向找到答案。另外分享一个小技巧:把常用软件的安装命令整理成一个脚本文件放在云盘或者代码仓库里,换机器或者重装系统时直接跑,比每次现查现装省事得多,也能顺手当作文档,告诉别人你的环境是怎么搭起来的。