
装过几十个 Homebrew 包之后我越来越不想打开终端去做那些重复的brew update、brew outdated、brew upgrade操作。明明只是想看一眼哪个软件有新版本却要先敲一串命令再在一堆紫色高亮的字符里找关键信息。后来我换上了 BrewUI这个用图形界面接管 Homebrew 管理工作的工具彻底改变了我维护这台 Mac 的方式。BrewUI 不是一个“用来替代 Homebrew 的东西”它是 Homebrew 的可视化管理驾驶舱。底层仍然是 Formula、Cask、Tap、Dependency 这些概念但所有的操作从“记住命令 阅读输出”变成了“看列表 点按钮”。如果你也和我一样机器上装着几十上百个包或者你身边有刚接触 macOS 开发环境、一看到终端就头大的朋友我强烈建议你了解一下这个项目。这篇内容不是我对着官方文档念参数而是我把 BrewUI 作为日常主力工具用了几个月之后沉淀下来的完整使用经验从安装到核心功能从依赖冲突到服务管理再到哪些场景真的没必要用它。文章偏长但每一步都是实际操作过的你可以直接照着来。1. 受够了命令行先聊聊为什么需要 BrewUI1.1 macOS 包管理的前世与命令行的真实痛点要弄懂 BrewUI 解决了什么得先明白 Homebrew 本身是怎么回事。Homebrew 是 macOS 上最主流的包管理器它用统一的命令来安装、卸载、更新那些开源软件和命令行工具。你装 Node.js、Git、FFmpeg、Python 这类东西大多数时候都会先想到brew install。但问题出在“管理”这两个字上。安装一个新包很简单麻烦的是后续的维护你装了 80 个包其中有 20 个有依赖关系每次brew update之后都会有新的版本冒出来你需要在终端里盯着输出分辨哪些是你要升级的、哪些是依赖自动升的、哪些升完可能会破坏别的包。还有更琐碎的磁盘空间不够了想清理旧版本brew cleanup会告诉你节省了多少空间想改一个软件源你得去编辑环境变量想给 MySQL 做开机启动brew services start mysql这串命令你得记得住。这些操作本身不复杂但频率一高就变成了一种持续的精神占用。尤其当我同时用好几个开发环境的时候哪个环境用的什么版本、谁是谁的依赖在终端里看brew list --tree的输出虽然够用但可读性真的很差。1.2 BrewUI 到底把什么变成了“看得见”的东西BrewUI 的核心思路很简单把 Homebrew 的数据库、配置、状态全部用图形界面呈现出来。它读取的不是抽象的中间输出而是 Homebrew 的原始数据然后把它们整理成可以被扫一眼就理解的界面。我的体感是它带来了三个维度的变化。第一状态可视化。所有已安装的包、有新版本的包、过时的包、存在依赖问题的包一眼就能分辨不用在终端输出里慢慢找。第二操作可逆化。界面上做的每一个动作其实底层还是在调用 brew 命令但它会给你确认的机会而且日志输出比纯终端更直观。第三管理变成了“浏览”而不是“记住命令”。你不需要去记brew cleanup --dry-run还是brew cleanup -n界面上就是一个“清理”按钮点击之前它会告诉你准备做什么。1.3 谁适合用谁其实没必要用先泼一盆冷水BrewUI 不是所有人必备的工具。如果你只装了五六个包一个月只 update 一次那继续用命令行没问题别给自己增加一个需要维护的软件。BrewUI 更适合下面这几类人电脑上装了 30 个以上 Homebrew 包或 Cask 应用已经记不住自己装了些什么需要频繁管理依赖关系比如做 iOS/Android 开发、Flutter 开发、多版本语言环境切换运营或产品同事偶尔要用 Homebrew 装个工具但对终端不熟对那些“把机器搞得一团糟”的场景有焦虑希望能预览操作后果再执行。我自己属于第一类和第二类的混合体这台开发机的brew list输出超过 80 行。在这种数量级下BrewUI 带来的效率提升是非常明显的。2. 安装 BrewUI 前后的环境准备与首次运行2.1 前置依赖别跳过的 Homebrew 本体BrewUI 只是一个“壳”它依赖具备完整功能的 Homebrew。所以在安装 BrewUI 之前请先确保设备上已经装好 Homebrew并且执行过至少一次brew update让本地数据库处于正常状态。这里要提醒一个很常见的误区很多人以为 BrewUI 内置了 Homebrew或者装完 BrewUI 就不用管 Homebrew 了。不是这样的。BrewUI 每次做操作本质上都是在该用户权限下调用 brew 二进制执行任务只是把输出和交互包装成了图形界面。你可以打开终端输入brew --version如果能正常输出版本号并且类似于Homebrew 4.x.x就没有问题。如果提示 command not found请先安装 Homebrew/bin/bash -c $(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)这里再补一条请确认你的机器架构。Apple Silicon 设备上 Homebrew 的默认前缀是/opt/homebrewIntel 设备是/usr/local。BrewUI 首次启动时会自动探测前缀但如果你之前手动设置过HOMEBREW_PREFIX或者有多个 Homebrew 安装目录就得在 BrewUI 的配置里把路径指对。2.2 下载与安装的几种方式BrewUI 本身不是通过brew install brewui装的至少我写这篇内容时还没有正式的 Formula主流的安装方式是去项目的 GitHub Releases 页面下载编译好的 dmg 或 zip解压后拖进 Applications 目录。也有一些用户选择从源码构建git clone https://github.com/你的仓库地址/BrewUI.git cd BrewUI swift build -c release源码构建的好处是能第一时间体验新功能坏处是你得准备好 Xcode Command Line Tools而且每次都要自己拉代码编译。如果你只是想拿来管理软件包直接下载发布版就行。下载完拖进 Applications 后第一次打开 macOS 可能还会弹“已阻止”之类的提示。这是 Gatekeeper 在拦未经公证的第三方应用。遇到这种情况不用急着关掉 SIP 或者乱敲 sudo 命令最简单的方式是在 Finder 里右键点击应用图标选择“打开”然后在弹出的确认框里再点一次“打开”。这种处理方式只对当前应用生效是最安全的绕过手段。2.3 首次启动的权限问题与目录识别BrewUI 首次启动会让你选择 Homebrew 前缀它一般会自动识别出/opt/homebrew或/usr/local中的正确那一个。这个步骤千万别选错选错会导致后续所有操作都报“找不到 brew”或者“Permission denied”。紧接着它会请求访问你的 Keychain 或者开发者工具权限。具体取决于版本和运行方式如果它调用了 git 或 ssh 相关的资源属于正常现象因为brew update本身就是一次git fetch。授权的时候注意看弹窗提示确认是 BrewUI 在发起请求而不是其他可疑程序。我的安装过程中遇到过一个额外的问题第一次启动时它提示“Homebrew 数据库尚未初始化”但我明明已经装好并正常使用了。后来发现是我的 shell 配置文件里给HOMEBREW_PREFIX设置了自定义路径而 BrewUI 没有读取我 shell 里的环境变量。解决办法很朴素在 BrewUI 的设置界面手动填入实际前缀然后重启应用。这个情况比较少见但如果你自定义过环境变量遇到类似报错别慌先把这个因素排除掉。3. 核心功能逐项拆解与操作演示3.1 已安装包列表从“满满一屏字符”到“一张可检索的表格”BrewUI 的主界面核心是一个已安装软件包列表。每一行代表一个包列信息包括包名、版本、安装日期、大小、是否有更新、依赖了哪些包、被哪些包依赖。这些信息在命令行里要靠brew list、brew info、brew deps --tree分段查看而在 BrewUI 里它们都被整合在了同一个视图里。我最常用的一个能力是搜索。终端里也有brew list | grep xxx但 BrewUI 的搜索框是即时过滤的并且支持按“仅显示有更新”“仅显示 Formula”“仅显示 Cask”“仅显示无条件构建”等维度做筛选。比如我只想看哪些通过 Cask 装的 GUI 应用只要切换一个标签比敲brew list --cask舒服得多。这里顺便解释一下 Formula 和 Cask 的区别Formula 是命令行软件和库比如 git、ffmpegCask 是图形界面应用比如 Google Chrome、Visual Studio Code。BrewUI 会在界面里明确区分这两类因为它们的管理策略不同。Cask 应用的升级往往需要下载一个完整的安装包耗时更长BrewUI 会单独列出它们的升级状态。3.2 搜索、安装与卸载按钮背后其实还是 brew 命令BrewUI 的搜索本质上就是调用brew search的后端数据在界面上提供了一个输入框和结果列表。你在搜索框里输入node它会匹配 formula 名称、Cask 名称甚至是描述文字然后你在结果列表里点了“安装”它就开始执行brew install node。别小看这个“点击安装”的动作BrewUI 做的比裸命令更友好的一点它在执行安装之前会显示将要执行的完整命令以及该包的全部依赖列表。比如你装 ffmpeg它不会直接一路装下去而是先把依赖树展开给你看告诉你“这个包会引入 24 个子依赖总下载量约 XX MB”。装完之后它还提供一个日志面板记录每一步输出方便你在出问题时跟踪。卸载也是同样。选中包点卸载它默认会带上--ignore-dependencies的选项确认。为什么不是直接递归删除所有依赖因为有些依赖是共享的你卸载这个包并不代表别的包不再需要它。BrewUI 的处理方式是默认只卸载当前选中的包然后提示你“检测到以下包不再被其他包依赖”让你决定是否清理。这种“多步确认”在命令行里几乎没办法做得这么直观。3.3 更新与升级从小心谨慎到游刃有余brew update和brew upgrade是有区别的这个区别在 BrewUI 里被表达得格外清楚。update是更新 Homebrew 自身的仓库记录把远端最新的 Formula 索引拉下来upgrade才是根据索引升级你机器上已经安装的包。在 BrewUI 的“更新”页签里它会先展示 update 的状态然后在下方列出一大堆“可升级”的包每一个都标注了当前版本和目标版本。我可以勾选我真正想升级的那几个点“升级所选”也可以直接全选执行。这在终端里需要手动写命令组合而在图形界面上就是一次勾选操作。有一个我特别喜欢的细节BrewUI 升级 Cask 应用之前会先检测该应用当前是否在运行。如果有进程占用它会弹出提示问你是强制退出还是要忽略。这一点真的救了我很多次。用命令行的时候我经常遇到Error: It seems there is already an app at ...就是因为忘了退出 Google Chrome 或 Docker Desktop然后操作中止重新入锅。BrewUI 在升级前就把这个障碍提前告知了。3.4 清理与维护磁盘空间回收的艺术Homebrew 用久了机器里会积压大量旧版本的 Formula特别是那些带版本的库像node14、python3.9一个包可能同时存在两三个版本。brew cleanup能帮你清掉旧版本但很多人不敢乱跑怕误删。BrewUI 把清理做成了“预览 执行”模式。在清理界面里它先扫描所有不再被引用的老版本文件列出每一项占用的磁盘空间左下角汇总“清理后可释放 XX MB”。我盯着列表确认里面确实是那些不会再用的老版本再点执行。它内部调用的是brew cleanup -s这里的-s代表 scrub还会清缓存结果输出也非常清晰。还有一个藏在维护里的实用功能它可以一键重写 Homebrew 的缓存目录~/Library/Caches/Homebrew。这个目录虽然不起眼但积少成多后体积相当惊人尤其是那些经常安装大型 Cask 应用的用户。BrewUI 的清理面板会单独列出缓存大小你可以一键清空效果立竿见影我第一次用直接释放了 3 个多 GB。4. 依赖关系与冲突处理4.1 依赖树可视化把 brew deps --tree 变成一张真树Homebrew 的依赖关系是使用中最大的隐性成本。你装了一个包它自带八个依赖你升级其中一个依赖可能导致另一个包出问题。在命令行里brew deps --tree输出的是一大段用缩进和符号拼出来的树状文本能看懂但不好看。BrewUI 把依赖树做成了真正的图形化界面。在任何一个包里展开“依赖”标签页你会看到它下面挂着一整棵依赖树父节点和子节点通过连线连接点击任意子节点可以继续往下钻取。更关键的是它支持“反向依赖”视图选中一个包可以看到“谁在依赖我”。这个功能在排查爆炸性升级时价值极高。举个例子有次我想把 OpenSSL 升级到最新 3.x但不确定影响面。在 BrewUI 里搜索 OpenSSL切到反向依赖页只见底下密密麻麻挂着二十几个包从 Python 到 Postgres全部依赖旧版 OpenSSL。看到这个结果我说什么都没去动它因为那样的升级牵扯实在太广了。过去我在终端里只能靠brew uses openssl虽然也能查出反向依赖但不会有如此直观的视觉冲击。4.2 常见冲突场景与界面上的解决方案依赖冲突是 Homebrew 使用中最让人头皮发麻的问题。最常见的冲突形态是同一软件存在两个版本比如你同时装了python3.9和python3.11某些包的编译会因为你 PATH 里的版本不对而报错。BrewUI 有一套“冲突检测”机制在包详情里它会对比当前已安装的其他包标出它们之间是否存在版本竞争或者文件覆盖风险。比如你安装postgresql15的时候它会提示你当前已存在postgresql14并且二者的二进制路径会有重叠或替代关系让你选择是共存还是先卸载旧的再继续。我实际遇到过的比较复杂的冲突是 glibc 和 GCC 版本引起的问题不是 GUI 应用层面的东西纯粹是底层编译链。BrewUI 不可能帮你解决所有编译错误但它能把冲突的源头可视化地展开告诉你“A 依赖 2.0B 依赖 1.9现在你装了 2.0B 编译不过”。这比我在终端里翻一长串编译日志找哪里版本不匹配要直观得多。4.3 卸载时“连带卸载”的判断误区很多用户在界面上看到“卸载前提以下包不再依赖它”就会直接点清理认为这就是“安全卸载依赖”。我因为太信任自动判断踩过一次坑。情况是这样的我用 BrewUI 卸载了某个不再需要的旧 Ruby 版本它提示“检测到有 3 个包不再需要这个 Ruby 的运行时依赖”我顺手点了全部清理结果其中一个工具在下次启动时报错因为那个工具虽然不依赖 Ruby 运行时但它的一个编译期组件引用了这个路径。BrewUI 的判断依据是 Homebrew 的依赖元数据它不会去扫描每个二进制文件实际链接的动态库所以“元数据上不再依赖”不等于“运行时真的用不到”。从那之后我给自己定了个规矩卸载说白了不差那一两分钟的扫描时间先多点开几个包看看它们的反向依赖再决定要不要连带清理。BrewUI 支持你在清理前逐项点击查看详情这个步骤值得花时间。5. Taps、服务与应用内更新策略5.1 可视化管理 Tap 仓库Tap 是 Homebrew 扩展仓库的概念。默认情况下你用brew install走的官方仓库但很多软件并不在官方源里需要通过brew tap添加第三方仓库。比如一些数据库驱动、特定公司的内部工具都藏在各种 tap 仓库里。BrewUI 里有一个单独的 Tap 管理模块会列出当前机器上已添加的所有 Tap每个 Tap 对应一个 GitHub 仓库地址。你可以从这里直接查看该 Tap 里包含了哪些 Formula也可以勾选删除一个 Tap。删除 Tap 在命令行里是brew untap user/repo在 BrewUI 里也相当简单——而且它会警告你“此 Tap 当前被 XX 个已安装包引用”避免你误删仓库导致包信息无法追踪。我还在这里发现过一个实用的冷知识你可以很清楚地看到官方 Tap 和自建 Tap 的更新时间。如果你发现某个软件搜不到很可能是你那个 Tap 很久没有更新了在 BrewUI 里刷新一下再试问题迎刃而解。5.2 Homebrew Services 的图形化开关Homebrew Services 是管理后台服务、守护进程的一个扩展功能。比如你通过 Homebrew 安装了 MySQL、PostgreSQL、Redis、Nginx你可以用brew services start/stop/restart来让它们开机自启或者停止运行。很多用户第一次听到 brew services 时已经被各种参数劝退了。BrewUI 把 services 做成了一个开关列表界面左边是服务名右边是状态标签和启动/停止按钮。我可以在同一屏看到所有服务此时此刻的运行状态点一个钮就能切换开机自启状态。这个功能的实际意义远大于“图个方便”。举个例子我本机同时装了 Redis 和 PostgreSQL用命令行的时候经常忘记某个服务还开着导致端口冲突或者启动速度变慢。用 BrewUI 之后每次开机我扫一眼 services 面板一目了然。更重要的是它会把服务的日志文件路径标出来方便你排错时去翻日志。这一切在命令行里要走brew services list、brew services info xxx好几步才能拿到在 BrewUI 里全部集中呈现。5.3 应用自身更新的注意事项BrewUI 也遵循大多数 macOS 应用的习惯在设置里提供“检查更新”的按钮或者提示“新版本可用”。但它本身也是伴随 Homebrew 生态发展的它的更新频率未必和 Homebrew 的更新节奏同步。我的建议是BrewUI 不需要追新除非你在某个版本遇到了 bug。这里说一个具体的版本适配问题。有一段时间我升级了 Homebrew 到新版 4.x结果 BrewUI 的旧版解析不了 4.x 新格式的 metadata界面里很多包的状态显示成了“未知”。我没急着卸载 BrewUI先查了它的更新日志等作者发布了兼容新版 Homebrew 的版本后升级解决。所以我建议那些长期使用 BrewUI 的用户当 Homebrew 那边有 major version 升级时暂缓操作等 BrewUI 发布兼容更新然后在 BrewUI 里更新它自己这是最稳的路径。6. 实测体验中的性能表现与常见问题6.1 大数据量下的流畅度与资源占用我的开发机上安装的包数量在八十个上下加上依赖BrewUI 每次启动后加载全部列表差不多需要两三秒。这个速度可以接受毕竟它不仅要读包的安装信息还要去解析每个包的 metadata 和依赖关系。但它有一个值得注意的性能特点在触发“检查更新”这种操作时它其实等于后台跑了一个brew updatebrew outdated这个过程在终端里可能需要十秒到几分钟不等界面上的表现是有一个进度条在转。如果你按了“刷新”然后又去点别的按钮偶尔会出现“操作排队”的情况这是正常的因为底层同一个 brew 命令在同一时刻只能跑一个。我在使用中已经养成了习惯触发刷新后先看一眼不着急去点别的东西。资源占用方面BrewUI 平时驻留的内存大约在 200 MB 到 400 MB 之间作为 GUI 应用不算离谱。如果你追求极致的轻量那它确实不如终端零开销但它换来的是可读性和操作效率我认为值得。6.2 与命令行、脚本的兼容性BrewUI 会不会和命令行之间产生冲突这是很多用户担心的问题。从我的使用经验来看两者是不会互相打架的BrewUI 只是 Homebrew 的另一个前端它操作的是同一套数据库、同一个安装目录所以你用命令行装的包会在 BrewUI 里出现反之亦然。但我建议你注意一件事不要在同一时刻在终端里和 BrewUI 里同时跑两个 brew 操作。因为 Homebrew 自身很忌讳并发写操作比如你在 BrewUI 里正在brew upgrade又跑到终端执行brew install其中一边会报错“Another active Homebrew process is already in progress”。这不怪 BrewUI是 Homebrew 的全局锁机制。配合使用时讲究一个先后顺序就不会有任何问题。我个人的习惯是日常的查看、浏览、升级选择走 BrewUI遇到批量、精确参数的安装或复杂的自定义编译配置时回到命令行操作。两者互为补充而不是互相排斥。6.3 遇到问题时的排查顺序用 BrewUI 这些年我碰到过几次“界面里看到的和终端里执行的不一样”的情况。整理一套自己的排查顺序分享给你先看 BrewUI 的操作日志面板它每次操作都会留下完整输出十有八九里面的报错信息能直接指明原因。回到终端手动执行同一条命令看是否复现。如果终端也报错那基本就是 Homebrew 本身的问题而不是 BrewUI。检查 Homebrew 版本和 BrewUI 版本是否匹配有没有 major version 的失配。清空 BrewUI 的本地缓存目录重启应用。有时纯粹是界面的状态数据过期了不是真的出错。如果还不行去项目的 GitHub Issues 搜关键词这种工具的用户群体不小你踩过的坑大概率有人已经问过了。第 2 步是定位问题最重要的一步。BrewUI 再怎么包装它执行的就是那些 brew 命令终端不通过它能直接验证。记住这个原理绝大多数“BrewUI 怎么不工作了”的问题都能在五分钟内定位到。7. 我的建议哪些场景请回到命令行更高效7.1 编辑器、脚本与自动化场景仍建议用 brew 命令BrewUI 做得再好它也是一个交互式图形程序不适合用在自动化场景。比如你想写个 shell 脚本在 CI 环境里批量安装依赖或者通过brew bundle根据 Brewfile 恢复一套完整的环境这些都应该继续用命令行。我自己的做法是brew bundle相关的工作完全留在终端。我用一个 Brewfile 文本记录了所有需要安装的包和 Cask 应用在重装系统或者换新 Mac 的时候一句brew bundle就全部装回来了。BrewUI 也支持查看当前包的清单但它的定位是浏览和操作单个包而不是批量恢复环境。还有一类场景也必须留在命令行你需要精确控制参数的时候。比如brew install带--build-from-source、--HEAD这类特殊选项BrewUI 的交互模型很难覆盖所有的 edge case。这种精细活儿命令行是唯一正确的工具。7.2 混合使用的最佳实践如果你问我日常份额怎么分配我的答案是大约七成用 BrewUI三成用命令行。BrewUI 管的是“看清楚 日常维护”命令行管的是“自动化 精确控制 批量操作”。具体到一天的使用流程里我一般是这样操作的早上起来打开电脑先瞄一眼 BrewUI 的更新页看看有没有依赖需要升级心里有个数需要装一个新的开发工具时先在 BrewUI 里搜索查看它的依赖树确认影响面后再安装如果我要一口气装一整套环境比如配一台新电脑时直接用终端跑brew bundle排查具体 bug 的时候终端看日志和依赖关系BrewUI 做辅助的图形化参考。这套流程磨合了相当长一段时间才稳定下来。最开始我总是想“既然有 GUI 了什么都用它点”后来发现效率反而下降然后又走向另一个极端只在 BrewUI 里看看状态其他全回终端又觉得没发挥它的价值。现在这个比例是我用起来最舒服的状态。最后再分享一个小技巧如果你经常在 BrewUI 里“清理旧版本”记得在清理前先看一眼它列出的“此项会释放 XX MB”的汇总数字连续观察几天摸清自己机器上的包增长规律。你会发现很多看起来巨大的“可清理空间”其实只是一两个大型 Cask 应用的历史安装包搞清楚来源之后你会对整台机器的存储占用有更清晰的掌控感而这一点恰恰是命令行给不了你的。