说个挺有画面感的场景。你打开终端,敲下一行brew install ffmpeg,下一秒屏幕刷出一长串“将安装以下依赖”,大概有二十多个名字,你一个都不认识。你犹豫了一下,还是按了回车。装完了,能用,但你始终没搞明白——这些依赖到底是干嘛的?哪个是核心?哪个能清掉?哪个动一下会让整个环境崩掉?
我就是在那个瞬间开始转向 GUI 工具的。BrewUI 这个项目,简单说,就是给 Homebrew 配了一个图形操作界面。Homebrew 本身还是那个 Homebrew,装包、卸载、升级、清理,底层命令一条没少,只是你不再需要盯着满屏的字符去猜测状态。它能看清单、看依赖关系、看更新日志,还能管理后台服务,把原本分散在好几条命令里的信息集中到一个窗口里。
这篇文章不是什么“最全指南”,就是我实际用下来的一整套流程、思考和一些踩坑记录。适合谁看?如果你已经装了 Homebrew,但觉得命令行管理软件包不够直观;或者你刚接触 macOS 上的包管理,想知道自己机器里到底装了什么、哪些能动、哪些不能乱动,那这篇文章应该对你有用。
1. 先搞明白:BrewUI 到底解决了什么问题
1.1 Homebrew 很强,但它的短板在哪里
Homebrew 是 macOS 和 Linux 上使用率很高的开源包管理器。它做的事情和apt、yum类似,但设计理念更贴近“个人开发者日常工具”这个定位。默认装到用户目录下(Apple Silicon 机器是/opt/homebrew,Intel 机器是/usr/local),不需要sudo就能安装和卸载大部分软件,这是它受欢迎的重要原因。
但命令行这个东西,信息密度低的时候很优雅,信息密度一旦上来就成了灾难。等你装了几十个、上百个包之后,用brew list看输出,满屏的公式名堆在一起,你根本分不清哪个是当初主动装的,哪个是依附在别的包身上的依赖。想知道“如果我卸载这个包,会牵连哪些东西”,命令行还得敲半天,先查 reverse dependencies,再去理依赖树,普通人根本不会为了看一眼去折腾这些。
更麻烦的是 Formula 和 Cask 的区别。Formula 是命令行工具和底层库,比如wget、nginx、ffmpeg;Cask 是带界面的软件,比如 Visual Studio Code、Docker Desktop。二者在命令行里混在一个brew list输出里,新手根本分不清。BrewUI 做的第一件事,就是把这两种软件分开展示,让信息结构一眼可见。
1.2 BrewUI 的核心定位:给 Homebrew 一个合理的操作台
BrewUI 本质上不是一个“新包管理器”,也不是 Homebrew 的替代品。它的核心思路是:所有增删改查操作仍然由 Homebrew 完成,BrewUI 只是在一个图形窗口里帮你组织命令、展示输结果、分析依赖关系。
它最让我满意的设计是“透明”。界面上每一次实际操作,比如安装一个包、清理缓存,它会在后台调用对应的brew命令,并在日志区域把完整输出展示出来。这意味着如果你哪天想彻底搞懂底层逻辑,完全可以在终端里敲同样的命令对照着看。GUI 不是黑盒,它更像一个把底层命令显式化的壳。
几个核心模块大概是这样的:
仪表盘:展示当前系统里已安装的 Formula 和 Cask 数量、可更新数量、磁盘占用情况。包列表:分页浏览所有已安装和可安装的软件包,支持搜索、版本查看、依赖查看。依赖关系视图:以树形或列表方式展示某个包的依赖项和反向依赖项。服务管理:可视化管理brew services启停的后台服务。清理工具:一键执行brew cleanup,识别不再被依赖的孤包袱,并展示删除后的效果评估。偏好设置:配置 brew 可执行文件路径、API 域名等环境变量。
这些功能单拆出来,每一条你都可以用终端命令完成,但把它们放进一个界面里,意义就不一样了。人脑天生不擅长处理几百行的字符流,但擅长理解图表和分组信息。BrewUI 做的就是把几百行输出转成你能“看懂”的结构。
1.3 什么样的人适合用,什么人留在命令行更好
用了一段时间之后,我认真想过这个问题:GUI 工具是不是“新手专属”?答案是未必。
| 使用者类型 | 终端操作体验 | BrewUI 体验 | 建议 |
|---|---|---|---|
| 刚接触 Homebrew 的新手 | 容易被依赖关系和命令输出吓到 | 能直观看到包和依赖,减少迷茫 | 强烈建议先用 GUI 上手 |
| 日常管理几十个包的用户 | 清单很长,查找、比较麻烦 | 搜索、筛选、批量操作效率高 | GUI 和 CLI 混用最舒服 |
| 重度开发者,装机就为了跑几个工具 | 命令熟,效率高 | 多余操作反而打断思路 | 留在命令行完全没问题 |
| 运维/脚本化场景 | 命令可以写进脚本 | GUI 不支持自动化 | 命令行是不可替代的 |
我自己的状态是:日常巡检和批量清理用 BrewUI,写脚本和快速装包还是用命令行。两者并不冲突,反而互补。
2. 动手之前:环境准备和安装方式
2.1 先确认 Homebrew 环境正常再谈 GUI
装 BrewUI 之前,最忌讳的事就是 Homebrew 本身的安装路径和权限已经是乱的。GUI 只是一个操作壳,壳再好看,底层环境有问题,最终报错还是得靠命令行排查。
所以建议先做两件事。第一件,确认 brew 版本:
brew --version正常输出会有版本号,比如Homebrew 4.x.x。如果没有,说明你只是装了 GUI 没装 brew,那问题就大了。第二件,跑一次体检:
brew doctor这个命令会帮你检查 Homebrew 的目录结构、权限、链接、环境变量等是否正常。如果输出一堆警告,建议先处理掉再继续。常见的比如“unbrewed dylibs were found”或者“Your system is ready to brew”,前者意味着系统里有绕过 Homebrew 安装的动态库,后者才是好状态。
另外,理解一下目录结构会很有帮助。Apple Silicon 机器上,/opt/homebrew是 brew 的家,下的软件都装在里面;/opt/homebrew/etc放配置文件,比如你装 nginx 之后它的nginx.conf就在这;/opt/homebrew/var放运行数据,包括 MySQL 的数据目录和服务的日志。BrewUI 虽然不要求你记住这些路径,但当你调试服务或者手动改配置时知道它们在哪会节省大量时间。
2.2 三种安装方式,按场景选一种
BrewUI 的安装方式并不复杂,同样是“怎么方便怎么来”,但在动手前先给你提个醒:尽量通过官方渠道下载,别去第三方站点要安装包。
方式一:从 GitHub Releases 下载.dmg文件。这是最直接的方式,下载后打开、把图标拖进 Applications 文件夹即可。macOS 的 Gatekeeper 可能会在你首次打开时提示“来自未知开发者”,这是正常现象。右键图标选择“打开”,系统会再给你一次确认机会,只要你确认文件哈希对得上,就没有问题。
方式二:通过 Homebrew 自己安装。这个很有意思,毕竟 Homebrew 本质是个命令行工具,但你也的确可以通过 Cask 来安装它的图形界面:
brew install --cask brewui这样做的优点是版本跟随 brew 的索引自动更新,删除时brew uninstall --cask brewui也会把应用连同相关缓存一起清理干净,比手动删垃圾文件省事。
方式三:源码编译。适合想自己改源码或者不太信任预编译包的人。
git clone https://github.com/brewui/brewui.git cd brewui swift build -c release编译完成后二进制会生成在.build/release/目录下。用源码编译的好处是可以用最新 commit,但相应地,你需要本地有完整的 Swift 工具链,而且发布时间和上游仓库同步,风险自己承担。
三种方式对照一下:
| 方式 | 优点 | 缺点 | 适合人群 |
|---|---|---|---|
| 下载 dmg | 简单直接,不依赖网络 | 需要手动检查签名/哈希 | 大多数普通用户 |
| brew cask 安装 | 更新方便,卸载干净 | 依赖 brew 本身正常 | 已经熟练用 brew 的人 |
| 源码编译 | 可定制,可学习 | 编译时间久,需要工具链 | 开发者 |
无论选哪种,装完之后启动应用,先在偏好设置里看一下“brew 可执行文件路径”。大多数情况下 BUI 会自动探测,默认是/opt/homebrew/bin/brew或/usr/local/bin/brew。如果你是用自定义路径安装的 Homebrew(通过设置HOMEBREW_PREFIX),就必须手动指定,不然应用找不到 brew,就完全没法工作。
2.3 首次启动:为什么很慢,要不要慌
第一次打开 BrewUI,你大概率会看到它卡在“正在载入软件包列表”的阶段。整个过程可能在几十秒到几分钟不等。不用慌,这背后是有原因的。
Homebrew 本地有一个“公式索引”,记录了所有可安装的软件包信息。BrewUI 第一次启动要把整个索引读进来,再和系统已安装的包做匹配,同时要读取每个已装包的信息,这个量级通常在数千个条目。另外,如果你的网络状态对 GitHub API 的访问不理想,索引的拉取会进一步拖慢启动过程。
我遇到过一个细节:启动时界面显示“正在读取安装状态”反而比“正在更新索引”要快。后来想通了,因为软件包元数据是一大批 static 数据,最多几百 MB;而已安装包的依赖关系计算涉及递归查找,慢是正常的。
所以第一次启动别急着点来点去,让它把索引完整载完。如果实在卡死,直接关掉重新打开一次,大多数情况下第二次会比第一次快很多,因为缓存已经在本地了。
3. 实操篇:用 BrewUI 完成第一次完整的包管理任务
3.1 主界面到底看什么
打开 BrewUI 之后,你会看到主窗口左侧是几个功能面板,右侧是主要内容区域。这布局我第一眼觉得过于朴素,但用久了才发现,这种“少即是多”是对的——它太清楚自己只是一个操作前端,而不是一个花哨的 app。
最上方的搜索栏是我用得最多的入口。比如我想找wget,直接输入关键词,界面会把所有名称或描述里包含wget的 Formula 和 Cask 同时列出来。这不只是“找到软件”这么简单,它会顺带告诉你当前系统里有没有已装,如果有,已经装的版本号是多少,可更新的版本是多少。
点进任意一个包,详情页分成几块:
基本信息:版本号、许可证、维护者、来源仓库地址。依赖项:这个包依赖哪些东西。反向依赖:系统里有哪些包依赖这个包。安装路径:如果已安装,具体文件放在哪里。
这个页面是我觉得比命令行更好用的地方。brew info wget也能输出这些信息,但它是线性文字,看了后面忘前面。图形界面把几块信息平铺开,扫一眼就能得出结论。
值得特别说的是“反向依赖”这一栏,它非常容易被人忽略,却是避免事故的关键。任何你打算卸载的包,都应该先看一眼这里。如果显示“被 2 个包依赖”,那你直接卸了它,那两个包轻则功能缺失,重则启动失败。
3.2 安装一个软件包:点击之后发生了什么
在 BrewUI 里装一个新包很简单:搜索到目标,点“安装”,确认弹窗,进入进度页。但“点一下”背后发生的事,还是值得拆解一下。
表面上是 GUI 收到了你的指令,实际上它后台运行了一条类似这样的命令:
brew install wget如果wget有依赖,brew 会先解析依赖树,把缺失的依赖一并装入。这个过程和命令行一模一样,唯一的区别是 BrewUI 会把每一步输出都实时显示在日志面板里。你能看到它先下载依赖的 bottle(预编译包)、然后解压、再执行必要的链接操作,最后完成。
这里有一个 GUI 工具普遍存在的坑:如果 brew 在安装过程中需要交互式输入,比如某个公式需要你确认或输入密码,GUI 往往无法处理这种交互提示。好消息是绝大多数常规 Formula 和 Cask 安装都不需要交互,但如果遇到卡住的情况,先看一眼日志区域。如果它在等待输入,最快的办法是切回终端,手动执行同样的命令,处理完交互之后,再回到 BrewUI 继续。
装完之后,BrewUI 会在软件名称旁边打一个绿色对勾,显示当前版本号。如果你去终端跑brew list --versions wget,结果是一样的。GUI 和命令行双验证,能帮你建立信任感,也方便逐步理解底层发生了什么。
3.3 更新管理:不要一看到“全部更新”就手滑
Homebrew 的更新机制分两步:brew update是更新本地的索引信息,让 brew 知道现在有哪些新版本可用;brew upgrade才是真正把已安装的包升级到新版本。BrewUI 把这两步放在一个“检查更新”按钮里,但执行时是分开的,这一点很多人没注意。
界面上会有一个“可更新”列表,列出所有有新版本可用的包。每个条目显示当前版本和新版本,有些还附带变更链接,点进去可以看到这次版本之间改了什么。信息丰富,是 GUI 的优势;但选择多也有选择多的麻烦——你很容易一看到红点就忍不住点“全部更新”。
我的建议是:工作机上别随便全量升级。
原因很简单。Homebrew 的升级是连依赖一起升级的,你升级 A 的时候,它可能顺手把 A 依赖的底层库 B 也给升了。如果 B 被另一个正在运行的软件 C 依赖,C 很可能因为 B 的行为变化出现兼容性问题。这在命令行时代是“升级一时爽,排查火葬场”的经典案例,BrewUI 只是让这个问题更显眼,并没有消除它。
所以我现在的习惯是分三档处理:
- 日常开发工具(如 git、ripgrep、jq):有更新就随手点,风险低,收益明显。
- 核心服务类软件(如 nginx、mysql、postgresql):先看清楚变更日志,挑稳定版本更新,更新后立刻检查服务状态。
- 大型桌面应用(Cask 类):不着急,等一周看看社区反馈再更新。
如果你对某个包特别敏感,害怕意外更新,BrewUI 可以把它固定住不参与升级。这种“固定版本”的操作,本质上是在brew pin和brew unpin之间切换。被固定的包会出现在一个单独的列表里,更新的时候自动跳过。
3.4 卸载和清理:删包之前先想三件事
卸载包比安装包更需要谨慎。在 BrewUI 里看到一个包不爽,点卸载,界面通常会弹出一个提示:“这个操作会卸载 xxx,以及它的 X 个依赖(如果这些依赖不再被其他包使用)。”
很多人第一次看到这个提示会很开心,觉得一键删干净,方便。但我要泼一盆冷水:这个“不再被使用”的判断,系统是基于“依赖关系图”计算出来的,它不等于“你真的不需要它了”。
举个例子。你装了imagemagick,它的依赖里有一个libpng。后来imagemagick卸载了,系统发现libpng没有被其他包依赖,于是自动移除。但你在另一个项目里直接引用了libpng的动态库,或者某个服务是通过dlopen方式加载它的——brew 不知道这些,它只看“包对包的依赖关系”,不看你系统里的隐式使用。这种情况,连夜排查崩溃的阴影就会找上门。
所以我在卸载前会做三个检查:
- 反向依赖检查:BrewUI 里直接看,如果还有包依赖它,就不卸载。
- 本地是否有服务在用它:如果你的服务脚本里显式调用了它的二进制路径,卸载等于切断手脚。
- 依赖不被别的包共享:这个判断稍微难一点,看“依赖项”和“反向依赖”的实际关系。
清理缓存则没有这么多心理负担。brew cleanup会删除旧版本的安装包缓存和无用的临时文件,在 BrewUI 里点击“清理”它会先列出可释放的磁盘空间,让你确认后再执行。这一步基本上可以放心做,最多只是下一次换版本时重新下载罢了。
4. 进阶玩法:Services、Brewfile 和依赖可视化
4.1 用 GUI 管理 brew services,少开好几个终端
Homebrew 自带一个brew services子命令,用来管理后台服务类软件。这个功能很强大,但它又是典型的“藏在命令后面的能力”——不看文档根本不知道brew services start nginx会注册一个开机自启的服务。
BrewUI 把服务管理放在了左侧面板的一个独立入口里。它会列出当前所有通过 brew services 管理的服务,每个服务后面有状态标签(started、stopped、error、none),以及几个操作按钮。
启动一个服务很简单:选中服务,点“启动”,然后在弹出的下拉里选择“仅本次启动”或者“开机启动”。“仅本次启动”对应brew services run,不会注册自启;而“开机启动”对应brew services start,会创建 LaunchAgent 配置,下次开机自动拉起来。
服务日志的处理是我觉得比较惊喜的地方。以前排查服务问题,我要自己记日志路径,比如 nginx 的错误日志在哪、MySQL 的日志去哪看。BrewUI 在服务详情页里直接提供了“查看日志”按钮,点击之后会打开实时输出窗口。它做的事情和tail -f一样,但入口更友好。对不爱记路径的人来说,这能省不少事。
要注意的是,服务管理页面的状态信息来自brew services list,它读取的是 LaunchAgent 的注册信息。如果你在终端手动启动过服务,GUI 里也会同步显示,因为底层读的是同一份配置。反过来,如果 GUI 显示为“未注册”,但你明明感觉服务在跑,大概率是有其他方式启动的服务,比如 Docker、容器或者 launchd 直接加载的 plist 文件,这类就不归 BrewUI 管。
4.2 Brewfile:把整套软件清单变成一个小文件
Brewfile 是 Homebrew 的一组“清单文件”机制,允许你把当前机器上所有通过 brew 安装的软件导出成一个文本文件。这个文件的用途是迁移环境:新机器上只要有了这个文件,一条命令就能把旧机器的软件环境复刻过来。
导出命令是:
brew bundle dump默认在当前目录生成一个Brewfile,里面是类似这样的内容:
tap "homebrew/cask" brew "git" brew "wget" cask "visual-studio-code" cask "docker"BrewUI 把这个操作做成了两个按钮:“导出 Brewfile”和“导入 Brewfile”。导出时它会自动读取当前系统已安装的 Formula 和 Cask 列表,生成一份标准格式的文件,你可以选择保存到任意位置。导入时,它读取文件内容并列出预期安装的所有软件,确认之后逐条执行安装。
有几个经验值得说一下。
第一,Brewfile 记录的是顶层包,不会记录依赖。也就是说导出时你不会看到几十行依赖项,因为还原时 brew 会自动解析并安装依赖,不需要你操心。
第二,如果你用mas(Mac App Store 命令行工具)安装过应用商店的软件,Brewfile 里也会记录mas "App名称"这样的条目。前提是当前机器上装了 mas,否则导入时会报错。
第三,Brewfile 一定要用版本管理工具存起来。我会把它放到个人 git 仓库里,顺便加一个小脚本把 Dotfiles 一起管理起来。换电脑这件事,以前是噩梦,现在只需要拉取仓库再导入 Brewfile,基本上半小时搞定环境。
4.3 依赖可视化:当你的软件列表超过 50 个,这一页是救命稻草
依赖可视化是 BrewUI 里我最看重的功能之一,也是命令行无论如何都难以替代的部分。
当你打开任意一个包的依赖视图,界面上会生成一颗依赖树:根节点是当前包,第一层子节点是它的直接依赖,再往下是间接依赖。有些包复杂到需要展开三四层,比如浏览器的内核相关库,或者媒体处理工具链。如果你只是用终端跑brew deps --tree wget,输出会是一长串字符画的树,密密麻麻难以阅读。
BrewUI 的依赖视图还有一个反着来的功能:反向依赖解释。你选中系统里任意一个包,它会反着查一遍,找出哪些包依赖它。这个信息最大的用处是排查“为什么系统里有这个包”——很多时候你看到某个名字觉得陌生,以为可以删,一查反向依赖,发现它是某个你常用的软件的底座,瞬间就明白了。
依赖冲突排查也是一个实用场景。当你装新包时遇到“与已安装包冲突”的报错,BrewUI 会在依赖图里高亮显示冲突双方的关系,让你直观看到是哪两个包在争抢同一个文件。虽然它不能直接帮你解决冲突,但至少能让你迅速定位问题。
5. 遇到过的坑和排查记录
5.1 GUI 显示和命令行的状态不同步
这个问题出现的频率比我想象中高。现象是:BrewUI 列表里显示某软件“未安装”,但你切到终端一敲brew list --versions,发现它明明装在里面;或者反过来,GUI 显示已安装,终端却说没有。
排查思路是第一确认是不是忘了刷新。BrewUI 的索引是应用启动时加载的,如果你在 GUI 开着的时候用终端安装了一个新包,GUI 不会自动感知。解决办法是点击界面上的刷新按钮,或者重启应用。
接下来确认没有“两个 GUI 同时在操作”。如果你同时打开了 BrewUI 和另一个 GUI 包管理器,或者两个 BrewUI 实例,系统里会有多个 brew 进程在跑。Homebrew 自身有锁机制,同一时间只允许一个进程修改环境,但锁不会阻止你界面乱点,只是后面的进程会等待。这也是状态不同步的常见来源。
最后,如果前两种情况都排除了,去日志区看是否有报错。有时是 brew 索引损坏,导致 GUI 读取失败。这种情况下刷新无济于事,需要先在终端执行:
brew update --force --quiet把索引重建一遍,再重启 GUI。
5.2 brew update 卡住或超时
“正在检查更新”转圈超过五分钟,这个场景大多数人应该都遇到过。原因通常是网络对 GitHub 资源的访问不稳定,或者本地缓存有损坏。
我的处理顺序是:
- 先看日志区,如果卡在
Updating Homebrew...,大概率是网络问题,不是软件问题。 - 取消操作,稍等几分钟重试一次,避开繁忙时段。
- 如果持续失败,可以考虑把 brew 的更新源切换到镜像。这是一个比较常见的优化手段,核心是设置几个环境变量,告诉 brew 从不同的 HTTP 源获取索引和二进制包。在 BrewUI 的偏好设置里有对应环境变量配置项,填进去保存即可。
- 如果怀疑本地缓存损坏,可以用
brew cleanup --prune=all清理缓存,或者删除Library/Caches/Homebrew下的临时文件。注意别删错,先备份。
实测下来,大多数“卡住”的根因就是网络策略和源地址质量,和 BrewUI 本身无关。在终端验证brew update正常之后,回到 GUI 基本也就正常了。
5.3 锁文件和权限问题
“Waiting for another brew process...” 这句话,在 GUI 里会直接显示成一条无法忽略的红色横幅。原因很简单:Homebrew 在/opt/homebrew/var/homebrew目录下有一个锁文件,任何进程执行修改操作时都会拿锁,拿不到就等。
这种情况一般发生在两个场景。第一个是上次安装或升级过程中你强行退出了 GUI,导致锁没有释放。第二个是你同时用命令行和 GUI 操作 brew,一个在等另一个,而你忘了终端里还挂着一条命令。
解决办法是等。给当前进程几秒钟,一般会自己释放。如果等了几分钟还卡着,可以在终端检查是否有残留的 brew 进程:
ps aux | grep brew如果没有明显进程在跑,再去看锁文件的位置。但请注意,不要随手删锁文件。先确认没有进程持有锁,再决定是否清理。强行删除一个正在使用的锁,可能导致 brew 数据库状态错乱。
权限问题则是另一种风格。如果你启动 BrewUI 时提示“没有权限写入 Homebrew 目录”,大概率是/opt/homebrew目录的所有权被 root 占用了,或者之前用 sudo 运行过某些命令导致部分文件归属异常。排查方式还是回到终端:
ls -la /opt/homebrew如果确实有大量文件属于 root,可以考虑纠正所有权,但要仔细操作并先备份,涉及系统目录不建议盲目执行。最安全的解法是避免在 GUI 里处理需要权限的目录,回到终端解决权限归属后再继续。
5.4 卸载误删和“不能再启动”的服务问题
有一个我不能忘的教训。之前我在 BrewUI 里卸载了一个“看起来没用”的开发库,顺手把提示“不再被依赖”的几个包也点了删除。第二天,一个 Java 服务就启动不起来了,折腾半天才发现它通过 JNI 调用了那个库的本地接口。brew 不认这个,服务脚本也不在 brew 的依赖计算范围内。
从此我总结出一个规则:卸载“看起来没用”的包之前,先在反向依赖页面确认三遍;删除自动依赖时,默认不勾选“同时删除不再被依赖的依赖项”。
如果真的出了问题,也不要慌。Homebrew 的卸载并不会删除配置目录,只是移除二进制和动态库。你可以重新通过brew install装回来,服务的配置文件还在,恢复成本很低。如果服务本身是由 brew services 管理的,重新安装后再在服务管理面板里点击启动即可,日志在/opt/homebrew/var/log下,排查起来也方便。
另一个会坑人的操作是直接删 brew 服务目录下的数据。比如 MySQL 的数据目录在/opt/homebrew/var/mysql,有些人为了“彻底清理”直接把整个目录删了。这样确实能让 MySQL 重新初始化,但如果你没有备份数据库,后果非常严重。GUI 里的“清理”不会动数据目录,只会清理下载缓存和旧版本,这一点倒是可以放心的。
最后想多说几句
用 BrewUI 这段时间,我最深的体会是:GUI 不是用来“替代命令行”的,而是用来“解释命令行”的。它把 brew 内部那些隐式的依赖关系、服务状态、更新策略,变成你能看见、能理解的东西。等你看懂了一次,回到终端再敲同样的命令,心态会完全不一样。
最后分享一个小技巧。我每周五会固定做一个“环境巡检”:打开 BrewUI,看一眼可更新的软件版本,逐个确认变更内容,再决定哪些更新、哪些继续等;顺手看一下服务管理里有没有异常状态的服务,然后把 Brewfile 导出一次提交到 git 仓库。这套流程加起来不到半小时,但让我对自己的开发环境始终心里有数。
你可以从今天开始,下载 BrewUI,先不急着操作,点开几个已安装的包看看依赖关系就够了。这会是一个挺有意思的起点。