在macOS上折腾了这么多年,我几乎所有开发工具都交给了Homebrew,也就是那个敲一行brew install就能装软件的包管理器。可时间一长,问题就来了:brew list一拉就是两百多个包,有些是当年装来体验一下就再也没用过的,有些是某个大软件的依赖,根本不敢乱删。每次想清理,面对一堆命令行输出都得先做半天心理建设。直到社区里有人推荐了 BrewUI 这个图形界面工具,我才算把“装包靠命令、管理靠眼力”的日子过到头了。这个工具说白了一句话:给你的 Homebrew 配一个可视化控制台,装包、卸载、升级、看依赖、清理缓存,全都能用鼠标点着来。这篇文章,我就把从安装到日常使用的完整过程,连同我踩过的坑一起写下来,给同样被 brew 管理困扰的朋友留一份可参考的记录。
1. 为什么我会需要一个BrewUI
1.1 命令行再强大,也有看不清楚的时候
Homebrew 的命令其实不算难,install、uninstall、update、upgrade、cleanup这几个背下来基本够用。但“能用”和“好用”是两回事。当系统里的包数量超过几十个,依赖关系开始变得像蜘蛛网之后,纯靠命令行的文字列表去管理,效率会明显下降。
我遇到过几个很具体的场景。第一,想知道某个包为什么会被装进系统,用brew uses --installed formula或brew deps --tree --installed确实能查,但输出是一大串缩进符号和名字,看久了眼睛真的会花。第二,想清理没用的依赖,命令是brew autoremove,但这个命令只会告诉你“我要删掉下面这些”,却不会直观地展示这些依赖到底被谁依赖、删了之后有没有别的包受影响。第三,升级的时候brew upgrade一股脑全部更新,有时候某一个大版本更新会把你的开发环境搞挂,等发现问题再想回滚,就得翻brew list --versions记录,非常被动。
这些场景里,命令行不是做不到,而是信息表达方式太“原始”。人要理解树形结构、理解依赖关系,眼睛看图形永远比读文本更快。这就是我开始找图形界面工具的根本原因。
1.2 UI不是要取代终端,而是补上“俯瞰视角”
一开始我心里有个疑问:给 brew 加个界面,是不是多此一举?毕竟命令行那么灵活,GUI 功能肯定有阉割。后来实际用了 BrewUI 我才想明白,这种工具的设计定位并不是“替代终端”,而是“补充全景视角”。
终端操作是精确打击,你清清楚楚自己要做哪件事,比如“我要安装 node”、“我要卸载 postgresql”,直接敲命令是最快的。但当你不知道自己“应该做什么”、需要先了解系统现状的时候,比如“我装的东西到底有多大”、“哪些包很久没更新了”、“哪些依赖已经没人用了”,终端就没那么友好了。BrewUI 这类界面工具,最大的价值是提供一个“俯瞰视角”:打开之后所有包的当前状态、可升级数量、缓存占用、依赖关系一目了然,你只需要看着屏幕做判断,剩下的点击都由工具翻译成对应的 brew 命令去执行。
BrewUI 的底层逻辑也是这么设计的——它本质上是把 Homebrew 的命令封装成一个个可视化的操作按钮,并没有自己另搞一套软件安装体系。这意味着它的行为逻辑和命令行完全一致,工具本身风险很低,不会出现“界面里显示装好了,命令行里却找不到”的割裂情况。
1.3 它到底解决了什么问题
用了一段时间后,我觉得 BrewUI 适合三类人。第一类是刚开始接触 Homebrew 的新手,对命令行不熟,怕敲错命令把环境搞坏,图形界面能让你看到每个操作的效果,学习成本更低。第二类是跟我一样装了几百个包的老手,需要定期体检系统、清理无用的依赖、查看磁盘占用,界面能节省大量时间。第三类是单纯讨厌黑窗口的人,能用鼠标解决的问题绝不打字。
至于具体的价值点,我总结为五条:包的安装卸载更直观、依赖树可视化、更新与升级可控化、缓存和孤儿依赖清理一目了然、所有操作都有操作日志可回溯。这五条基本覆盖了日常 brew 管理的全部高频操作。
2. 安装准备与环境要求
2.1 环境检查,缺一个都跑不起来
BrewUI 毕竟只是 Homebrew 的“外壳”,所以前提条件是系统里必须先有 Homebrew。另外它还需要图形界面运行环境和一些基础工具,建议在动手前先把环境确认一遍,免得装到一半报一堆莫名其妙的错。
打开终端,逐一执行下面这三条命令,看看输出是否正常:
sw_vers brew --version xcode-select -psw_vers查看 macOS 系统版本,BrewUI 通常要求 macOS 11 及以上;brew --version确保 Homebrew 已经安装且版本不是太老;xcode-select -p检查 Xcode Command Line Tools 是否安装,正常会输出/Library/Developer/CommandLineTools,如果没有输出说明需要先执行xcode-select --install安装命令行工具。
我实际遇到过的情况是:Homebrew 版本太旧,导致 BrewUI 调用某些命令时报错。如果你也是老用户,建议先跑一遍brew update && brew upgrade,把 brew 本身升级到最新,再装 BrewUI,能省掉很多麻烦。
2.2 安装方式二选一
BrewUI 目前的安装方式有两种,一种是直接通过 Homebrew 装,另一种是下载源码本地运行。我推荐第一种,因为后续升级、卸载都方便,跟系统整体管理逻辑一致。
方式一,终端执行:
brew tap brewui/brewui brew install --cask brewuibrew tap是把 BrewUI 官方的仓库添加到本地源,brew install --cask brewui是把它作为 GUI 应用安装。装完之后,它会出现在你的应用程序目录里,图标是一个很简洁的咖啡杯加几个节点线条的图形,名字就叫 BrewUI。
方式二,从 GitHub 仓库拉源码跑本地开发版,适合想自己改代码或者尝鲜最新功能的人:
git clone https://github.com/brewui/brewui.git cd brewui make setup make run源码方式比较折腾,需要本机有 Go 和 Node.js 环境,而且每次更新要重新拉代码。日常使用的话,我用的是第一种官方 cask 方式,稳定省心。这里提醒一下:如果你是 Apple Silicon 芯片的 Mac,建议确认 brew 是安装在/opt/homebrew路径下的,BrewUI 会自动识别;如果是 Intel Mac,默认路径是/usr/local,两者它都能兼容。
2.3 首次启动,先认清楚界面
安装完成后,在启动台找到 BrewUI 打开。首次启动它会花几秒钟扫描本机已安装的所有包,这一步相当于把 brew 的数据库读进内存,扫描速度取决于包的数量,两百个包大概需要十几秒。界面出来后,整体布局很清晰,总共分四个区域:
- 左侧是分类导航栏,区分 Formula(命令行工具)和 Cask(图形应用),还能一键切换到“可升级”“孤儿依赖”“已损坏”等筛选视图。
- 中间是包列表区,显示每个包的名称、版本、安装时间、占用大小,支持搜索和排序。
- 右侧是详情面板,选中任意一个包后,会显示它的依赖关系、被哪些包依赖、官方描述、安装路径等信息。
- 顶部是操作栏,包含刷新、同步数据、执行清理、全局设置等按钮。
我用 ASCII 简单画个示意图,方便你对照:
+--------------------------------------------------+ | BrewUI [刷新][设置] | +----------+-----------------------------+----------+ | 全部包 | 包名称 版本 大小 | 详情 | | Formula | -------------------------- | 依赖树 | | Cask | node 22.11.0 68MB | 被依赖 | | 可升级 | python 3.13.1 120MB | 安装路径 | | 孤儿依赖 | nginx 1.27.4 35MB | 操作按钮 | | 已损坏 | ... | | +----------+-----------------------------+----------+首次打开不建议急着操作,先花几分钟把列表从头翻一遍,看看自己到底装了什么,心里先有个底。这一步我每次重装系统后都会做,有时会翻出许多自己都忘了装过的东西。
3. 核心功能拆解与实操要点
3.1 包列表与一键管理
BrewUI 最基础的功能就是包管理。中间列表区分 Formula 和 Cask 两种类型,这是 Homebrew 特有的概念:Formula 是命令行工具,比如 git、node、wget 这类;Cask 是带图形界面的完整应用,比如 Google Chrome、Visual Studio Code、iTerm2 等。在 BrewUI 里,这两种类型会在列表上打标签区分,看起来非常直观。
搜索框支持模糊匹配,输入关键字后,包列表会实时筛选。选中一个未安装的包,右侧详情面板底部会显示一个“安装”按钮,点击后顶部会弹出实时日志窗口,里面滚动输出的是brew install的原始日志,装完会变成“已安装”状态。已安装的包则显示“卸载”按钮,点击后会弹二次确认框,因为卸载操作不可逆,一旦确认就会执行brew uninstall。
这里有几个自己的心得想分享:
- 卸载前一定要先看右侧面板的“被依赖”栏。如果一个包被其他多个包依赖,比如
openssl,你贸然卸载会把一堆依赖它的软件一起拖坏。BrewUI 会在这时给出红色提示,但最终确认还是要你自己判断。 - 搜索时注意区分 Formula 和 Cask,因为很多软件恰好两边都占,比如
node是 Formula,而visual-studio-code是 Cask。 - 安装等待过程中别频繁点击,重复操作会导致 brew 任务队列堆积,出现互相等待的锁。真遇到这种情况,终端执行
rm -f "$(brew --prefix)/var/homebrew/locks/"*.lock清掉锁文件再重试。
3.2 依赖关系可视化,替代一串树形命令
这个功能是我最喜欢 BrewUI 的地方。在详情面板里有一个“依赖树”标签页,点开之后,当前包依赖的所有子包和反向依赖它的父包会以树状层级展开,单击任意节点就能跳到那个包的详情。
以前用命令行查依赖,靠的是brew deps --tree --installed,输出是一大堆竖线和加号构成的纯文本树,眼睛要在符号和包名之间反复横跳。换了 BrewUI 之后,依赖关系变成可点击的可视化树,哪个包是哪个包的上游,一眼就明白。
我举个例子。比如你选了mysql,依赖树会显示它依赖openssl@3、protobuf、zlib等。翻到“被依赖”标签,又能看到mysql-client、某些 ruby gem 依赖链里的包引用了它。这时候你就能判断:如果mysql不是你自己主动装的,而是被某个大软件带进来的,而且现在那个大软件已经卸载了,那它很可能就是可以清理的孤儿依赖。
实操上给大家一个建议:碰到不确定能不能卸载的包,一定先看两个维度——它依赖谁(卸载后哪些东西会没)、谁依赖它(它是被谁带进来的)。这两个维度分别在依赖树的两个标签页里,看明白再动手,安全性会大大提高。
3.3 更新检查与可控升级
Homebrew 的升级一向让我又爱又恨。brew upgrade一条命令能更新所有,但每次升级大版本我都担心有兼容性问题。BrewUI 把升级操作拆细了,顶部会显示一个“可升级”数字角标,点击左侧栏“可升级”分类,就会列出所有有新版本的包,并且能单独查看每个包的当前版本和最新版本号。
在可升级列表里,每个包右侧有一个独立的“升级”按钮,顶部还有一个“全部升级”的按钮。我的日常操作策略是:先看数量,如果可升级包只有两三个,基本无脑点升级;如果可升级包有几十个,那就得谨慎,先挑核心开发环境相关的包单独升级观察情况。
升级之前,BrewUI 允许查看该包的更新日志链接和发布页面,虽然不是内嵌网页,但能一键跳转。这一点很实用,尤其是那些跟随大版本走的工具,比如 Python、Node.js,大版本更新往往伴随破坏性变更,先看 changelog 再决定要不要升级,是每个老手都会做的事。
这里有一个我踩过的坑:某次看到nginx可升级,我没多想就点了升级,结果升级完配置文件的兼容性出了变化,本地环境直接起不来了。后来学乖了,凡是生产环境在用的服务类软件,升级前先看 changelog,升级前用brew list --versions记下当前版本,确认出问题后能通过brew install指定版本装回去。BrewUI 虽然能让升级变简单,但“升级有风险”这件事它替你做不了主。
3.4 磁盘占用分析与清理建议
macOS 用久了,Homebrew 的缓存和旧版本占用的磁盘空间相当可观。以前我清理靠命令,先brew cleanup --dry-run看看有哪些过期文件,再真正执行,加上brew autoremove处理孤立依赖。现在 BrewUI 把这两步合并成了一次可视化的“体检”。
具体位置在左侧栏的“存储空间”视图,打开后能看到三块内容:Cellar 里旧版本文件占用的空间、Caskroom 里已卸载应用的缓存残留、以及~/Library/Caches/Homebrew下载缓存占用的空间。每一项前面都有对应清理按钮,点击后 BrewUI 会先模拟计算出可释放的空间大小,再让你确认。
我第一回用这个功能时,系统里光 brew 相关的缓存和旧版本加起来就释放了 4.2GB,还是挺惊喜的。不过有个重要提示:
注意:清理旧版本不等于删除当前版本。BrewUI 的清理按钮执行的是
brew cleanup,它只会删除.git缓存里旧版本的安装包,不会动当前正在使用的版本,所以正常操作是安全的。但如果你有切换到旧版本测试的需求,千万别急着清理,比如python@3.10和python@3.12这种不同主版本并存的情况,清理有可能误伤你想要保留的旧版本。我的建议是:清理前先到包列表搜一下有没有多个版本并存,确定没有特殊需求再执行。
3.5 全局设置和偏好调整
BrewUI 的设置项不多,但每一个都挺值得过一遍。自动刷新开关,打开后每次进入前台会同步一次 brew 数据;启动时检查更新,可以控制 BrewUI 应用自身是否自动升级;主题切换支持跟随系统、浅色和深色;包显示模式可以切换是否显示那些“隐藏”的依赖包。
其中“显示隐藏包”这个选项比较有意思。默认情况下,BrewUI 会隐藏那些由其他包自动带入的依赖,只显示用户主动安装的“顶层包”。打开后会把全部依赖都平铺展示出来,数量可能瞬间翻倍,方便高级用户排查问题,但新手不建议开,看到一堆不认识的名字容易慌。
还有一个“点击安装包后自动关闭日志窗口”的开关,我建议关掉。因为安装失败时,日志窗口里的错误信息是排查问题最重要的线索,自动关闭了还得重新翻记录,非常麻烦。留着日志窗口,装完瞄一眼有没有Error字样,心里有数。
4. 实操记录:从安装到日常管理的完整流程
4.1 安装过程实录
我是在一台装有 macOS Sonoma 的 MacBook Pro 上装的 BrewUI,详细过程记录如下。如果你照着操作,应该能复现同样的结果。
第一步,更新 Homebrew 到最新:
brew update第二步,添加 BrewUI 的 tap 仓库并安装:
brew tap brewui/brewui brew install --cask brewui安装过程中终端会输出一些下载和分析依赖的日志,最后会显示🍺 brewui was successfully installed!之类的提示。然后启动应用:
open -a BrewUI首次启动会弹出权限请求,申请访问 Homebrew 安装目录的权限,这是为了读写包信息,点击允许。如果你的系统开启了严格隐私保护,还需要到“系统设置-隐私与安全性-完全磁盘访问权限”里手动勾选 BrewUI,否则它可能读不到某些包的安装信息。
启动完成后,顶部菜单栏会出现 BrewUI 的小图标,点击可以快速呼出主界面。它还支持开机自启,设置里打开就行,这个功能对经常需要处理 brew 事务的人来说挺实用。
4.2 用BrewUI完成第一次“包体检”
装好之后,我第一次正儿八经用 BrewUI 做了整套维护流程,目的就是给用了两年的系统“减负”。整个过程分四步,每一步我都在界面和命令行之间做了对照,确保行为一致。
第一步,查看包总数和构成。打开主界面,左边栏顶部显示“全部包 328”,其中 Formula 214 个、Cask 114 个。我把列表按“占用大小”倒序排,看看哪些包是大头。
第二步,找出“可升级”包。点左边栏“可升级”,显示 37 个。我没有直接全部升级,而是先挑出几个日常开发依赖的重型软件:python、node、go、imagemagick,分别点开日志确认升级内容后逐个升级。
第三步,查看“孤儿依赖”。点开“孤儿依赖”视图,显示 19 个包。我一个个过详情面板,凡是看到“被依赖”一栏为空的,基本都是可以处理的。当然也有例外,比如reattach-to-user-namespace是被 tmux 插件动态调用的,列表里可能不显示依赖关系,这种我会保守处理,先留着不删。
第四步,执行存储空间清理。在“存储空间”页面看到缓存占用 1.8GB,旧版本占用 2.3GB,点击清理,瞬间释放了 4.1GB。清理完成后我又执行了一次brew doctor,终端返回Your system is ready to brew,说明系统状态一切正常。
4.3 我的个人使用习惯
工具永远是辅助,真正重要的是形成一套适合自己的工作习惯。用 BrewUI 大半年之后,我总结了自己的套路:
- 每周一早上打开 BrewUI,先点“可升级”看看有没有关键包需要处理。有的话周内抽时间升级,没有就直接关掉。
- 每月做一次深度清理,流程是:看孤儿依赖、看存储空间、跑一遍
brew doctor。这套流程用 BrewUI 大概十分钟搞定,以前纯命令行得折腾半小时还容易漏。 - 安装新包之前,先到 BrewUI 搜索看看是不是已经存在了,避免重复安装。尤其是那些被某大软件带来的依赖,有时候你想装的工具其实已经在系统里了。
- 卸载重型软件前,会先在详情面板截图记录依赖关系,万一后面发现还有别的东西需要用到它,还能按图索骥装回来。
命令行我也没少用。有些操作 BrewUI 没做入口,比如brew services的启停、brew link的软链接管理,这些我都仍在终端里完成。工具是互补的关系,界面管全局、命令管精操作,两边同时用才是最高效的。
5. 常见问题与排查技巧实录
5.1 权限不足导致的操作失败
新手最容易遇到的问题是,通过 BrewUI 安装或卸载包时报权限错误,日志里能看到Permission denied @ rb_file_chmod或Operation not permitted这类字样。
这个问题的根源是 Homebrew 安装目录的所有者不是当前用户。尤其是旧版本 Homebrew 或从 Intel Mac 迁移过来的系统,/usr/local目录的历史权限比较混乱。解决办法也很简单,在终端执行:
sudo chown -R $(whoami) /opt/homebrewApple Silicon 芯片用/opt/homebrew,Intel 芯片用/usr/local。执行后再回到 BrewUI 刷新重试,绝大多数权限问题都能解决。
这里特别提醒一句:这个命令会把整个 brew 目录的归属权改成当前用户,如果电脑上有多个系统用户,需要注意其他人可能因此失去 brew 的管理权限。如果只是单机个人开发环境,基本没有风险。
5.2 界面一直卡在“正在同步”怎么办
有段时间 BrewUI 打开后一直转圈,显示同步中,等几分钟都没反应。排查思路是这样的:先看是不是网络问题导致 git 拉取 Homebrew 仓库超时,然后在终端手动执行brew update看能否正常返回。
如果终端里也卡住,通常是 Homebrew 仓库的远程 origin 指向的问题。我当时把镜像源做了一次检查和切换,用国内镜像替代默认源后速度明显提升:
git -C "$(brew --repo homebrew/cask.git)" remote -v git -C "$(brew --repo homebrew/core.git)" remote -v通过git remote set-url把远程地址换成可用的镜像地址,再执行brew update确认同步正常后,回到 BrewUI 点击“重新同步”即可。如果终端里brew update返回正常,只是 BrewUI 卡住,那多半是应用自身缓存问题,完全退出 BrewUI 再重新打开,或者清除它的缓存目录~/Library/Application Support/BrewUI再试。
5.3 UI 显示的包数量与命令行不一致
有个很常见的情况:界面上显示的可升级包数量和终端brew outdated输出的不完全一致。我遇到过多次,原因基本是缓存和命令超时。
brew outdated每次执行都会实时查询各仓库的 Formula 元数据,而 BrewUI 为了响应速度,默认使用的是本地同步缓存,同步间隔可能不是实时的。解决办法很简单,打开 BrewUI 后手动点击顶部“刷新”按钮,或者按Cmd+R强制刷新一次。如果刷新后还是不一致,检查一下是不是同时打开了两个包管理器实例,比如终端和 BrewUI 同时发起 brew 操作,导致 brew 的 git 状态被锁,刷新就会拿到不完整的数据。
另一个隐蔽原因:HOMEBREW_NO_AUTO_UPDATE环境变量。如果你曾经在 shell 配置里设置过这个变量,终端里执行 brew 命令时不会触发自动更新,而 BrewUI 启动时的刷新却会,二者看到的数据版本自然不一样。遇到这种情况,把环境变量的设置删掉或保持两边都统一,问题就解决了。
5.4 误卸载了重要包怎么恢复
BrewUI 的卸载按钮虽然做了二次确认,但人总有手滑的时候。真误删了也别慌,Homebrew 的设计本来就支持快速重装。打开终端,执行:
brew install 包名如果想恢复成原来的特定版本,先通过brew list --versions查看还有没有旧版本缓存,或者到包管理仓库查找历史版本。如果那个包是作为依赖被别的包使用的,重装顶层包时依赖会自动装回来。
我自己的教训是:卸载前一定要看右侧面板的“被依赖”列表。凡是显示被一个以上包依赖的,卸载时我会格外小心,必要时先截图存档。BrewUI 即使再方便,最后把关的仍然是你自己的判断力。
5.5 日志去哪看
当你遇到问题实在排查不出来,最直接的办法就是看日志。BrewUI 的应用日志存储位置为~/Library/Logs/BrewUI/main.log,里面记录了每次操作的详细过程,包括它调用的 brew 命令、返回值、错误输出。终端里也可以用brew doctor和brew config检查 brew 自身状态。BrewUI 出问题,九成是 brew 底层的问题,所以多用brew doctor排查,往往比盯界面更有用。
6. 与同类工具怎么选
6.1 主流 brew GUI 工具横向对比
BrewUI 并不是市面上唯一的 Homebrew 图形界面工具,之前比较有名气的还有 Cakebrew 和开源社区里的其他类似项目。我把几个工具的差异点整理成一张表,方便你根据需求选择。
| 对比维度 | BrewUI | Cakebrew | 自写脚本方案 |
|---|---|---|---|
| 安装方式 | brew cask 安装 | brew cask 安装 | 需要手工维护 |
| 依赖可视化 | 支持,树状交互 | 支持,但较简单 | 不支持 |
| Cask 应用管理 | 完整支持 | 部分支持 | 需另写 |
| 缓存清理分析 | 内置可视化统计 | 仅清理功能,无统计 | 需要命令 |
| 更新维护频率 | 高,社区活跃 | 较慢,处于维护模式 | 看自己 |
| 界面技术 | 轻量级,资源占用低 | Electron 较重 | 无界面 |
坦白讲,如果你只是偶尔装两个包,根本不需要任何 GUI,brew 命令就是最合适的。但如果你像我一样把 Homebrew 当主力包管理器,装了成百上千个包,需要定期维护系统,BrewUI 的投入回报比就非常高了。Cakebrew 当年也算经典,但开发活跃度不如 BrewUI,对新版 macOS 的兼容性也跟不上,我后来是因为 Cask 管理支持不完整才彻底切到 BrewUI 的。
6.2 我为什么最终留下了 BrewUI
选工具这件事,我最看重三样:底层行为透明、不额外引入脏包袱、维护活跃。BrewUI 完美踩中这三个点。它把 brew 命令包装在图形按钮后面,日志完全透明,你能看到每次点击到底执行了什么;它自己是轻量级的桌面应用,不会像某些 Electron 工具一样吃我几百 MB 内存;它的版本更新很频繁,说明有社区在持续维护,bug 修得也快。
当然它也不是没有缺点。比如对brew services的管理目前还没有完整覆盖,我得继续用命令行启停服务;另外界面默认语言是英文,国内用户可能觉得有点门槛,不过包名本身都是英文,影响不大。还有一个不便之处是首次同步需要一点耐心,包特别多的机器会慢一些。
我在实际使用中最喜欢的一个细节是:BrewUI 的卸载按钮边上,有一个不起眼的“查看依赖”按钮。每次我动了卸载念头,都会先点它确认一下有没有被其他东西依赖,这个习惯帮我避掉了至少三次环境事故。有时候工具的价值不在于它替你做了多少事,而在于它提醒你别做哪些事——这一点 BrewUI 做得比命令行好得多。