如果你在 macOS 上折腾过开发环境,那么 Homebrew 这个词你一定不陌生。装 Python、Git、Nginx、Redis,甚至一些 GUI 软件,很多人都靠那几行brew install撑起整个开发环境。但命令行这东西,用熟了确实高效,对新手来说却是一道门槛,哪怕是我这种老用户,偶尔也会遇到依赖关系理不清、卸载卸不干净、更新卡住半天不知道在跑什么的情况。后来我用到BrewUI,才意识到原来 Homebrew 也可以有更直观、更可控的操作方式。
这篇文章我就从实际使用的角度,聊聊 BrewUI 到底是什么、它把 Homebrew 的哪些核心能力变成了可视化操作、以及我用了这段时间踩过的坑和总结下来的实操经验。不管你是刚接触 Homebrew 的新手,还是被各种依赖和清理问题烦了很久的老手,这篇文章应该都能给你一些参考。
1. 先说清楚:BrewUI 到底解决什么问题
1.1 Homebrew 命令行的真实痛点
Homebrew 本身的设计思路是"少即是多"。它把软件包的管理抽象成几个命令:install、uninstall、update、upgrade、cleanup,日常使用确实够用。但一旦装的包多起来,问题就来了。
比如你想知道某个包被哪些其他包依赖,命令行里要敲brew uses --installed xxx,还要结合brew deps --tree xxx去看整棵依赖树,输出结果密密麻麻。再比如你想知道系统里有哪些包已经过时、哪些包是孤儿包(没有被任何包依赖),命令行也能查,但就是不够直观。还有更麻烦的场景:两个包同时依赖同一个底层库,可你想升级底层库又怕把别的包搞坏,这种时候靠命令行一点点梳理关系,效率很低。
另一个被很多人忽略的问题是卸载不干净。brew uninstall只卸载你指定的那个包和它独有的依赖,如果某个依赖同时被其他包使用,它不会动。时间一长,系统里积攒的残留依赖、缓存文件、旧版本压缩包越来越多,磁盘空间被吃掉不少。这个清理过程在终端里操作特别容易出错,因为你得先搞清楚哪些是可以安全删掉的。
1.2 BrewUI 是什么,以及它怎么定位
BrewUI,简单说就是给 Homebrew 套了一层图形化界面。它不是一个替代 Homebrew 的新包管理器,而是调用 Homebrew 底层能力的一个前端工具。也就是说,你在 BrewUI 里做的每一个操作,本质上都还是在执行brew命令,只是它帮你把命令背后的数据整理成列表、搜索框、按钮和状态标签。
这就带来一个很重要的好处:你不需要担心它会把 Homebrew 搞坏。因为所有关键操作依然走官方命令通道,BrewUI 只是在外部做展示和编排。它解决的是"信息展示不友好"和"操作有认知负担"这两件事,而不是另起炉灶。
从定位上看,BrewUI 解决的是这四类问题:
- 软件包的可视化搜索与浏览,不用记模糊的包名也能找到想要的东西。
- 依赖关系可视化,一眼看清谁是父包、谁是子包、为什么不能随便卸载。
- 批量操作入口,多个包一起升级、一起清理,不用一条条敲命令。
- 状态管理,哪些包需要更新、哪些服务正在运行,打开界面就能看到。
1.3 谁最适合用这个东西
我用了大概三个月,接触了不少用 BrewUI 的人,大概可以分成三类:
第一类是新接触 macOS 开发环境的人。他们刚开始用 Homebrew,记不住那么多命令,也搞不清brew upgrade和brew update的区别。BrewUI 的图形化界面能让他们先建立起"包管理器到底在干什么"的直观认知。
第二类是维护多台机器的开发者,或者需要经常帮同事排查环境问题的人。这类人通常不是不会命令行,而是觉得命令行一条条敲太慢,尤其是一台机器上有几百个包的时候,用 BrewUI 做整体审视效率更高。
第三类是想把系统维护做得更精细的人。比如定期清理缓存、检查孤儿依赖、管理后台服务,这些事情用命令行不是不能做,但用 BrewUI 可以一目了然,不容易误操作。
需要注意的是,BrewUI 并不适合所有人。如果你对 Homebrew 已经非常熟练,日常命令背得滚瓜烂熟,那它对你的价值有限。它的定位始终是"降低操作门槛、提升管理效率",而不是给你展示什么高端技巧。
2. 安装部署与界面上手
2.1 安装前置条件
在安装 BrewUI 之前,你的机器上需要先具备几个基本条件。
第一,必须已经装好 Homebrew 本身。这一步可以通过在终端运行官方安装脚本来完成,装好之后确认一下brew --version能正常输出版本号。BrewUI 所有的操作都依赖 Homebrew 的命令行接口,所以这一步必须保证环境是完整的。
第二,你的 macOS 版本不能太老。BrewUI 的界面框架对系统版本有一定要求,一般来说,保持系统在最近两三个大版本以内都没有问题。如果你还在用很老的系统,建议先把系统升级一下。
第三,网络环境得稳定。因为 BrewUI 在启动时需要读取 Homebrew 的本地数据,同时也会访问远程仓库检查更新,如果网络不稳定,界面可能打开得很慢,甚至出现数据加载不出来的情况。
检查完这三个条件之后,就可以正式安装 BrewUI 了。
2.2 安装 BrewUI 的完整步骤
BrewUI 的安装方式有不同的渠道,我常用的方式是通过 Homebrew 本身来安装。你没看错,BrewUI 自己也发布在 Homebrew 的仓库里,安装命令非常简单:
brew install brewui装好之后,直接在终端输入brewui就能启动:
brewui启动之后大概一秒钟就能看到主界面。如果你是第一次启动,它可能会花一点时间拉取本地软件包列表并建立索引,这个过程取决于你机器上已经安装了多少个包。我试过在一台干干净净的机器上启动,基本是秒开;在一台装了三百多个包的机器上启动,大概要等两三秒。
如果你不想每次都在终端敲命令,也可以把 BrewUI 固定到 Dock 栏。它安装之后会在应用程序目录里生成一个入口,你可以在启动台或者应用程序文件夹里找到它,拖到 Dock 上,以后就跟普通 App 一样点击打开。
安装过程中我遇到过一个小问题:如果之前 Homebrew 的权限配置有问题,BrewUI 启动时会提示无法读取某些目录。这个问题一般可以通过在终端执行brew doctor来诊断和修复,修复完再启动 BrewUI 就正常了。
2.3 界面布局和核心区域
BrewUI 的主界面并不复杂,整体分成几个区域,我用下来觉得设计思路很清晰。
顶部是搜索栏和操作按钮区。搜索栏支持按名称、描述甚至关键词模糊匹配,输入内容后下面列表会实时过滤。操作按钮区放着"清理"“升级全部”“检查更新”这类高频操作的入口,方便一键执行。
左侧是分类导航区。它会根据软件包的类型自动分类,比如普通命令行工具、图形化应用、字体、驱动等等。还有一个很重要的分类是"依赖库"——这类包通常不是你自己主动装的,而是作为其他包的依赖被拉进来的,单独列出来便于之后清理。
中间最大的区域是包列表区。每个包会显示名称、版本、当前状态(已安装、需要更新、未安装等)、体积大小、所属分类。点击任意一个包,右侧会展示这个包的详细信息,包括完整描述、依赖关系图、安装日期、最近更新日期等内容。
底部是一个状态栏,会显示最近一次操作的结果,比如"成功安装 3 个包""清理回收了 1.2GB 空间"这样的提示。
这个布局对于用过任何包管理器的人来说都很容易上手,几乎不需要学习成本。对于第一次接触的人来说,也比在终端里面对一堆命令输出要友好得多。
2.4 首启第一件事:配置软件源
默认情况下,BrewUI 使用的是 Homebrew 的官方软件源。网络好的地区访问官方源没有问题,但在网络条件不理想的时候,加载软件源信息会非常慢,甚至导致 BrewUI 卡在启动加载页面。
我建议你在第一次启动后,先去设置页面把软件源切换成国内镜像源。具体操作是在 BrewUI 的设置里找到"软件源"或者"仓库地址"选项,填入镜像源的 URL。这个操作本质上修改的是 Homebrew 的git remote地址,所以在 BrewUI 里改和命令行里改效果是一样的。
我个人的经验是,切换镜像源之后,不仅启动速度快了很多,软件包列表的加载、搜索的响应速度都明显提升。如果你想换回官方源,随时可以在设置里改回来,不会有什么副作用。
3. 核心功能实操:先搞清楚那些按钮背后在干什么
3.1 搜索与安装:本地清单还是远端实时查询
BrewUI 的搜索框是我用得最多的功能。它的工作方式跟brew search命令不太一样,默认是基于本地已经建立好的软件包索引做模糊匹配,所以响应速度非常快,基本是你敲完关键词,结果就出来了。
但这里有一个关键点你得知道:本地索引不是实时更新的。如果你在命令行手动安装了某个新包,或者 Homebrew 仓库里有新收录的软件,BrewUI 的搜索结果显示可能会有延迟。解决办法很简单,在 BrewUI 里点一下界面上方的"刷新"按钮,或者直接重启 BrewUI,它会重新同步一次本地索引。
安装操作的流程也很直接。在搜索结果里找到你要的包,点击进去查看详情,确认是你想要的东西之后,点"安装"按钮。BrewUI 会弹出确认窗口,展示将要执行的完整命令,比如:
brew install nginx这一点我觉得设计得很用心——它没有把命令完全藏起来,而是让你在点击之前能看到自己即将执行什么操作。对于想学 Homebrew 命令的新手来说,通过这种方式反而能慢慢建立起命令行操作的直觉。
安装过程中,BrewUI 会实时显示输出日志,跟终端里跑命令看到的输出是一样的。如果安装出错,错误信息也会直接显示在界面上,方便排查问题。
3.2 卸载不是点个垃圾桶那么简单
卸载这个功能看起来简单,实际上是最容易出问题的操作。
普通卸载很简单,找到包,点卸载按钮,BrewUI 执行brew uninstall 包名。但如果你只是这么用,迟早会遇到下面的情况:某些包卸载之后,它在安装时带来的依赖库变成了"孤儿",既没有其他包在用,也不会被自动清理掉。久而久之,这些残留的依赖越积越多。
所以我在使用 BrewUI 卸载软件时,一定会留意它界面上显示的一个额外信息——"卸载后剩余的孤儿依赖"。BrewUI 会在卸载前做一个依赖分析,告诉你这个包卸掉之后,会产生哪些不再被需要的依赖库。界面上还会给出选项:
- 仅卸载该软件
- 卸载软件并清理所有相关孤儿依赖
我建议大多数场景下选择第二种。但要注意,BrewUI 的分析结果是基于当前系统状态的,如果你不确定某个孤儿依赖之后还会不会被其他操作用到,可以先把情况截图记下来,确认之后再清理。
另外还有一个实用技巧:批量卸载。在 BrewUI 的列表里勾选多个软件包,然后统一执行卸载操作。这个功能在整理环境的时候特别好用,一次可以卸掉十几个不需要的包。不过在批量卸载之前,我建议你先用 BrewUI 的依赖分析功能看一下这些包之间的依赖关系,避免一次性把某个公共依赖库卸掉,导致其他软件无法运行。
3.3 依赖关系:为什么有的包不能直接卸
这是 BrewUI 做得最好的部分之一,也是我认为它跟纯命令行相比最大价值所在。
在终端里查看依赖关系,brew deps --tree输出是一大串树状结构,嵌套层级深了之后阅读起来很吃力。BrewUI 把依赖关系变成了一张可视化的图,父包、子包一目了然。你可以点击任意节点,查看这个包依赖了谁、被谁依赖。
理解这个关系对于日常维护太重要了。比如我曾经想升级系统里的 OpenSSL 库,但是在 BrewUI 里一查看依赖图,才发现有几十个包都依赖它。如果直接在命令行执行升级,风险很大,因为很可能牵动一堆软件的运行。后来我通过 BrewUI 看清了整条依赖链,先评估哪些包需要同步升级,才动的手,整个过程没有出现任何环境问题。
依赖关系对于卸载的意义也很大。当你尝试卸载某个包时,BrewUI 的交互逻辑是:先展示谁依赖了这个包,如果发现卸载它会导致其他包出问题,界面会明确提示,并且要求你确认。这个提示有时候看着有点烦,但它真的能救你的环境一命。
3.4 批量更新与版本管理
Homebrew 的升级机制对新手来说很容易搞混。简单来说:
brew update是更新 Homebrew 自身的软件源和公式信息。brew upgrade是升级你系统里已经安装的软件包。brew upgrade 包名是升级指定软件。
在 BrewUI 里,这些操作分得很清楚。打开"更新"页面,BrewUI 会先拉取最新的软件源信息,然后跟本机已安装的包做对比,列出所有有新版本的软件,并告诉你有多少包可以升级。你可以选择全部升级,也可以一个个勾选。
我个人的习惯是不要无脑全部升级。有些大型软件包,比如数据库、开发工具链,升级可能带来配置格式变化。还有一种是"系统级"的底层依赖,比如 Ruby 的某个核心库,贸然升级可能影响到别的开发工具。在终端里你很难批量筛出这些高风险包,但在 BrewUI 里,我可以先按"体积大小"排序,看看哪些包升级涉及的文件量大,再按"受影响依赖数"排序,看看哪些包升级可能牵动其他包。综合这些信息,再决定这一轮要升级哪些。
版本管理方面,BrewUI 也提供了一个很实用的功能:查看已安装软件的旧版本。Homebrew 默认升级后不会删除旧版本,方便你出问题时回滚。在 BrewUI 的"磁盘空间"分析页面,你直接能看到每个软件占用了多少空间,其中多少是旧版本压缩包。确认不需要回滚之后,一键清理即可。
4. 实际使用的完整场景演练
4.1 场景一:新机器迁移环境
换新电脑,最头疼的一件事就是把旧机器的开发环境重新搭一遍。以前我都是把旧机器上brew list的输出存到一个文本文件里,然后在新机器上写循环脚本去装。这个方法能跑通,但效率很低,还会遇到部分包装不上、某些包依赖报错的问题。
用 BrewUI 之后,迁移流程顺畅很多。操作逻辑大致是这样:
首先在旧机器上打开 BrewUI,在导出功能页面生成一份当前已安装软件包清单,格式可以是 JSON 或纯文本。把这份清单传到新机器上。
然后在新机器上确认 Homebrew 和 BrewUI 都装好,选择"从文件导入软件包列表"。BrewUI 会读取清单,自动跟当前 Homebrew 的可用包做对比,标记出哪些直接安装、哪些需要额外处理原因。处理原因通常包括:该包不在当前软件源、该包依赖版本等。你只需要确认一下,它就批量装起来了。
我实际操作下来的体感是,一份七八十个包的清单,大概半小时左右就能全部装完,而且装完之后界面上的依赖关系一目了然,不用像以前一样再手动去检查有没有遗漏的依赖。
4.2 场景二:清理长期未用的软件包
很多人装机一时爽,收拾环境火葬场。我用过一段时间的机器,brew list能列出一百多个包,但真正常用的可能就二三十个。剩下的不是当初实验装的,就是早已不用忘了删的。
BrewUI 给这类场景提供了一个非常直观的数据维度——"上次使用时间"。在列表里按这个字段排序,你一眼就能看到哪些包已经几个月没碰过。我会定期按这个维度做一次大清洗。
筛选出候选包之后,我不会直接批量删,而是先用依赖分析逐个确认一下。有的包虽然自己不常用,但其他包依赖它,删了会带来连带问题。BrewUI 在批量卸载界面上会显示这一层信息,确认安全之后再执行卸载。
清理完之后还有个步骤容易被忽略——清理下载缓存。Homebrew 每安装一个包,都会把源码包或者二进制包缓存在本地的~/Library/Caches/Homebrew目录下。时间长了,这里能积攒出好几个 GB 的空间。BrewUI 把这类缓存单独列在"清理"页面,你点一下清理,它会先展示可以释放多少空间,然后按确认执行。我试过最狠的一次,一次清理释放了 6GB 多空间。
4.3 场景三:管理后台服务
Homebrew 不只是装软件,还经常用来管理后台服务。比如装一个 Nginx、Redis 或者 PostgreSQL,装好之后要启动、停止、查看运行状态、设置开机自启。这些操作在命令行里是:
brew services start nginx brew services stop nginx brew services listBrewUI 把这个能力也搬到了界面上。在"服务"页面里,所有通过 Homebrew 安装的后台服务都会列出来,每个服务旁边有当前状态标签:绿色是正在运行,灰色是已停止。你要做的只是点击"启动"或"停止"按钮,不需要记命令。
这个页面对我来说使用频率很高。尤其是排查某个服务是不是挂了、端口是不是被占用的时候,以前要在终端里ps aux | grep nginx加上lsof -i来来回回查,现在打开 BrewUI 扫一眼状态就够了。
有一个小细节提醒一下:brew services管理的服务和系统自带的 launchd 服务不是一回事。BrewUI 展示的只是 Homebrew 装的那些服务的状态,如果你想管理系统服务,还是得用系统自带的工具。这一点别搞混了。
4.4 场景四:查看某个包的关联文件
有时候你发现磁盘空间莫名被占用,又不知道具体是什么文件。这时候可以用 BrewUI 的"文件透视"功能。选中任意一个包,它会列出这个包安装到系统中的所有文件路径,并且按目录分类展示。
我记得有一次排查一份异常日志,日志内容一直报某个库文件找不到,但 Library 目录下明明有这个名字的文件。后来我用 BrewUI 查看了对应安装包的文件列表,发现它实际安装的是另一个版本,只是因为路径软链指向错了,导致运行时找不到。这个排查过程在纯命令行下要多花不少时间。
另外,如果你对某个包的具体安装位置有疑问,这个功能也可以直接回答。比如 Python 装到了哪里、Nginx 的配置文件在哪个目录,不用which再加brew --prefix拼来拼去,直接在 BrewUI 里看文件列表就行。
5. 常见问题与排查技巧实录
用 BrewUI 这几个月,我遇到过一些奇怪的问题,也帮朋友排查过几次。这里整理几个高频问题,以及对应的排查思路。
5.1 BrewUI 显示"无法连接到 Homebrew 仓库"
这个问题出现得比较多,通常分两种情况。
一种是你很久没执行过brew update,本地软件源信息跟远端仓库之间有大量差异,BrewUI 在同步时超时。这种情况我建议先在终端里手动跑一次brew update,跑通了再重开 BrewUI。如果终端能跑通而 BrewUI 连不上,那问题多半出在 BrewUI 配置的代理或者仓库地址上。
另一种是网络环境本身有限制,访问官方仓库速度极慢或被阻断。解决办法就是切换软件源,换成国内镜像地址。这个前面说过了,操作不复杂,效果立竿见影。
5.2 安装软件时提示权限错误
BrewUI 在安装软件时偶尔会提示权限错误,比如目录没有写入权限。这个问题的根源通常不在 BrewUI,而是 Homebrew 目录的属主不对。
Homebrew 一般安装在/opt/homebrew(Apple Silicon 机器)或者/usr/local(Intel 机器)目录下。如果这些目录的属主不是你当前用户,就可能会出现权限问题。
排查方法很简单,打开终端输入:
brew doctor它会自动检查目录权限并给出修复建议。按建议执行修复命令,然后再打开 BrewUI 重试安装。另外提醒一句:不要试图用chmod粗暴地给 Homebrew 目录改权限,用brew doctor推荐的修复方式最安全。
5.3 清理缓存后,磁盘空间没减少多少
有朋友跟我吐槽过这个问题——在 BrewUI 里执行了清理,但看了一眼磁盘空间,变化不大。这里有两个原因:
一个是 Homebrew 的清理默认只删除"过时"的缓存,也就是那些已经不用的下载文件和旧版本压缩包。如果你近期没有执行过大的升级操作,缓存本来就很少,清理后效果自然不明显。
另一个更隐蔽的原因是,真正占空间的可能是其他目录,比如 Docker 镜像、Xcode 缓存、模拟器数据等。BrewUI 只负责 Homebrew 相关的文件,管不到这些。判断到底什么占空间,建议用系统的存储管理工具先扫一遍,再针对性处理。BrewUI 能做的是把自己的"责任田"清理干净。
5.4 升级某些大软件包时卡住
批量升级时,个别包可能会卡住很长时间。这个不一定是你操作的问题,也可能是软件包本身比较大,编译时间长。
我在 BrewUI 里升级大型包时,通常会先看这个包是不是有预编译的 bottle 可用。界面详情里会标明"二进制安装包"还是"需源码编译"。如果是源码编译,安装时间会成倍增加,而且对网络要求也更高。遇到这种情况,建议在升级前确认一下时间窗口,或者单独升级这一个包,不要跟其他包混在一起,避免整体进度被拖垮。
如果升级真的卡死,在 BrewUI 里可以强制终止当前操作,然后在终端里手动执行:
brew upgrade 包名 --verbose用详细模式跑一遍,能更清楚地看到它卡在哪个环节。
6. 一点进阶心得与建议
用 BrewUI 这段时间,我觉得它最大的意义不是替代命令行,而是把 Homebrew 的运作逻辑用更直观的方式呈现出来。很多以前一知半解的概念,比如依赖关系、孤儿依赖、bottle 和源码编译的区别,反而是通过这个工具真正搞清楚的。
平时给朋友推荐的时候,我会建议他们把 BrewUI 当作用来看数据、做决策的终端,而不是完全放弃命令行。遇到复杂的操作、需要精确控制参数时,该打开终端还是打开终端。两个工具配合使用,效果最好。比如我自己的习惯是:用 BrewUI 发现可更新的包并筛出高风险对象,然后在终端里针对这些包单独执行升级命令,同时观察详细输出。
另外一个小技巧:BrewUI 的依赖图功能在开发的时候特别好用。当你需要引入一个新库,又担心它跟已有环境冲突,先搜索这个包,查看它的依赖树,如果里面有你之前装过但是版本不同的库,就要提醒自己留意一下兼容性问题。
工具毕竟是工具,比工具更重要的是对软件包管理机制的理解。日常多花几分钟看看 BrewUI 展示的依赖关系、清理前后的体积变化,比闷头敲命令学到的东西多得多。这套流程跑顺了,macOS 上的软件管理就不太容易出幺蛾子了。