運(yùn)維一目了然)
1. BrewUI 到底是什么我為什么擱置純命令行來用它先說結(jié)論BrewUI 是 Homebrew 的一個(gè)圖形化客戶端本質(zhì)作用就是把你平時(shí)在終端里敲的brew install、brew services start、brew update、brew cleanup這些操作變成一個(gè)個(gè)看得見、點(diǎn)得到的界面按鈕和狀態(tài)面板。Homebrew 是 macOS 和 Linux 上用得最多的軟件包管理器平時(shí)大家叫它 brew用的都是命令行。你安裝 Python、Git、Redis、Nginx 這類開發(fā)工具很多時(shí)候都離不開它。而 BrewUI 這類工具解決的是另一個(gè)層面的問題命令行的反饋太抽象依賴關(guān)系太隱蔽服務(wù)狀態(tài)又不直觀。我會(huì)開始關(guān)注 BrewUI純粹是因?yàn)橐淮螌?shí)際需求。當(dāng)時(shí)我要維護(hù)一臺(tái)本機(jī)開發(fā)環(huán)境里面光是通過 brew 裝的東西就有六七十個(gè)有帶依賴的有被依賴的還有幾個(gè)開機(jī)自啟的服務(wù)。平時(shí)用命令行一條一條查比如brew list、brew deps --tree、brew services list都能查到信息但每次只能得到一個(gè)碎片。尤其是隔了兩周再回去看光靠終端里的文字流很難快速回答我到底裝了哪些東西哪些包很久沒升級(jí)可能已經(jīng)落后好幾版哪個(gè)服務(wù)現(xiàn)在還在跑、端口有沒有被占用這種問題。BrewUI 這類工具就是為這些問題出現(xiàn)的。它的適用人群我總結(jié)了三種剛接觸開發(fā)、終端命令還不熟練的新手能用圖形界面解決 tap、install、uninstall 這些操作減少學(xué)和記命令的成本。日常重度使用 brew但希望有一個(gè)上帝視角來總覽所有包、依賴、服務(wù)和磁盤占用的人。需要維護(hù)多臺(tái)機(jī)器、多個(gè)環(huán)境希望快速核對每臺(tái)機(jī)器軟件清單的人。當(dāng)然它不會(huì)替代命令行。比如寫腳本批量安裝、處理復(fù)雜依賴沖突、調(diào)試 formula 的構(gòu)建過程這些場景下終端依然是更高效的選擇。但 BrewUI 的存在是把 brew 從純工具變成了可被觀察的系統(tǒng)這一點(diǎn)非常值錢。2. 安裝 BrewUI 之前先把這幾個(gè)前置問題想清楚2.1 你的系統(tǒng)滿足運(yùn)行條件嗎BrewUI 本質(zhì)上是一個(gè)桌面應(yīng)用它會(huì)讀取本機(jī) Homebrew 的安裝信息并且調(diào)用 brew 的命令行接口去執(zhí)行實(shí)際操作。所以它并不是替代 brew而是 brew 的控制臺(tái)。這就決定了它有兩個(gè)硬性前提你的機(jī)器上必須已經(jīng)裝好了 Homebrew。這一點(diǎn)很多人會(huì)忽略以為裝了 BrewUI 就等于裝了包管理器其實(shí)完全不是一回事。macOS 版本要在 Homebrew 支持的范圍內(nèi)過老的系統(tǒng)會(huì)導(dǎo)致 brew 本身無法正常工作UI 再漂亮也沒用。還有一種情況是搭配 Linux 使用BrewUI 官方也支持 Linux 的版本。不過在 Linux 桌面環(huán)境下窗口環(huán)境差異比較大我還是建議先以 macOS 上的體驗(yàn)為主跑通了再折騰 Linux 側(cè)。2.2 安裝方式怎么選目前 BrewUI 的安裝方式我實(shí)際試用下來主要有兩條路各有利弊。第一種是直接下載安裝包。從 BrewUI 的 GitHub Releases 頁面下載 dmg 文件拖到 Applications 文件夾里就算裝好了。這種方式最簡單也最直觀適合所有用戶。缺點(diǎn)就是以后每次版本更新都要手動(dòng)下載軟件本身雖然有更新提示但操作路徑還是要你自己完成。第二種是通過命令行工具安裝。比如如果發(fā)布渠道支持 Homebrew Cask那一條brew install --cask brewui就能完成安裝。這種方式的好處是以后可以用brew upgrade統(tǒng)一管理升級(jí)。壞處是它要求你本來就熟悉命令行不然反而多了一道門檻。我個(gè)人的建議是如果你已經(jīng)用 brew 用了很久那盡量走 cask 的方式讓工具和自己的包管理器融合在一起維護(hù)成本最低。如果你還沒有這個(gè)習(xí)慣那就直接下載安裝包不糾結(jié)。2.3 首次啟動(dòng)的權(quán)限與數(shù)據(jù)說明BrewUI 第一次啟動(dòng)時(shí)會(huì)掃描你已經(jīng)安裝的所有 formula 和 cask。這個(gè)過程中最常遇到的坑是權(quán)限問題。Homebrew 在早期安裝時(shí)默認(rèn)會(huì)把目錄放在/usr/local下后來在 Apple Silicon 機(jī)器上變成了/opt/homebrew。如果你以前的權(quán)限配置比較混亂BrewUI 在讀取某些目錄時(shí)可能會(huì)因?yàn)闄?quán)限不足而顯示失敗。一個(gè)比較通用的處理方法是到終端里執(zhí)行sudo chown -R $(whoami) $(brew --prefix)/*這個(gè)命令的意思是把你自己的用戶設(shè)為 Homebrew 目錄的所有者。這也是 Homebrew 官方非常推薦的一種方式能大概率解決各種能讀不能寫能看列表但是操作失敗的權(quán)限問題。另外要提醒一點(diǎn)BrewUI 本身并不會(huì)繞過系統(tǒng)的 Gatekeeper 和隱私保護(hù)機(jī)制。首次啟動(dòng)訪問某些目錄時(shí)macOS 會(huì)彈出權(quán)限詢問窗口一定要允許。如果你直接點(diǎn)了拒絕后面會(huì)發(fā)現(xiàn)某些功能靜默失效這時(shí)候去系統(tǒng)設(shè)置 - 隱私與安全性里重新授權(quán)就好。3. 核心功能逐項(xiàng)拆解劃重點(diǎn)式的實(shí)操指南3.1 軟件包的搜索、瀏覽與安裝BrewUI 最基礎(chǔ)、也最好用的功能就是瀏覽和安裝軟件包。它的主界面通常分成幾個(gè)區(qū)域左側(cè)是分類導(dǎo)航中間是軟件包列表右側(cè)是詳情面板。搜索框支持模糊搜索比如你輸入nginx它會(huì)同時(shí)匹配 formula 名稱、描述、甚至維護(hù)者信息里包含關(guān)鍵詞的內(nèi)容。這里我要強(qiáng)調(diào)一個(gè)體驗(yàn)上的差異我覺得這也是圖形界面相對命令行最大的優(yōu)勢。命令行里brew search nginx會(huì)返回一堆候選列表但你對每個(gè)候選包只知道它存在不知道它是干嘛的。BrewUI 里直接可以看到完整描述、所屬組織、倉庫地址、最新版本、依賴列表、被哪些包依賴、安裝大小這些信息全部平鋪在一個(gè)頁面里一眼就能判斷要不要裝。安裝操作也很簡單。選中一個(gè)包點(diǎn)安裝按鈕BrewUI 會(huì)在后臺(tái)調(diào)用brew install命令然后把輸出日志實(shí)時(shí)顯示在界面上。這個(gè)過程中你不需要一直盯著終端裝完會(huì)彈一個(gè)通知。某些需要 sudo 密碼的安裝過程BrewUI 會(huì)調(diào)用系統(tǒng)的密碼輸入框而不是讓你去終端里敲這個(gè)細(xì)節(jié)對新手非常友好。但有一個(gè)坑要提醒BrewUI 里的安裝按鈕只管裝不管自動(dòng)處理沖突。如果某一個(gè)包需要特定版本的依賴而你已經(jīng)裝了另一個(gè)版本安裝過程可能失敗。這時(shí)候不要慌切到日志面板看失敗原因。大多數(shù)時(shí)候問題出在依賴版本沖突上處理方式跟命令行完全一樣手動(dòng)卸載或調(diào)整相應(yīng)依賴即可。3.2 更新與升級(jí)的節(jié)奏把控更新這塊是很多人安裝 BrewUI 之后用得最多的功能之一。其實(shí) brew 本身的升級(jí)邏輯很簡單brew update是更新 brew 自己以及各倉庫的索引brew upgrade是根據(jù)這些索引去升級(jí)所有已安裝的包。但命令行時(shí)代有一個(gè)痛點(diǎn)你不知道升級(jí)哪些包是安全的哪些包可能引起連鎖反應(yīng)。BrewUI 做的事情是把哪些包有可升級(jí)版本這件事變成了一個(gè)清晰的列表。你打開更新頁面能看到所有當(dāng)前可升級(jí)的包每個(gè)包都帶著當(dāng)前版本、最新版本、更新日志入口有的還直接顯示升級(jí)所需空間。這個(gè)信息密度在命令行里要翻好幾輪才能搞清楚。我在實(shí)際操作里形成了一套節(jié)奏這里分享出來供參考日常小版本升級(jí)比如 patch 版本可以直接在 BrewUI 里一鍵升級(jí)風(fēng)險(xiǎn)很低。涉及大版本跨越比如 Python 3.10 升到 3.11建議先看更新日志確認(rèn)兼容性再動(dòng)手。如果升級(jí)之后發(fā)現(xiàn)某些服務(wù)啟動(dòng)異常不要急著卸掉先用 BrewUI 的服務(wù)管理功能重啟對應(yīng)服務(wù)試試很多時(shí)候是新版本配置文件有差異導(dǎo)致的。3.3 服務(wù)管理最大驚喜在這個(gè)模塊BrewUI 里專門有一個(gè)服務(wù)管理模塊用來操作brew services這一組命令。這個(gè)模塊是真的好用。以 macOS 為例你通過 brew 安裝了 MySQL、Redis、Nginx 之后如果想要它們在開機(jī)時(shí)自動(dòng)啟動(dòng)命令行方式是brew services start mysql brew services start redis brew services start nginx如果想查看所有服務(wù)的運(yùn)行狀態(tài)brew services list這套命令很實(shí)用但缺點(diǎn)是不夠直觀。服務(wù)多起來之后你搞不清楚哪些是開機(jī)自啟的哪些是手動(dòng)啟動(dòng)的哪些雖然裝了但從來沒運(yùn)行過。BrewUI 把這些全部做成了開關(guān)每個(gè)服務(wù)一個(gè)面板狀態(tài)用顏色標(biāo)識(shí)比如綠色表示運(yùn)行中灰色表示未運(yùn)行。啟動(dòng)、停止、重啟都只點(diǎn)按鈕不用記憶服務(wù)名。支持查看每個(gè)服務(wù)的啟動(dòng)日志定位問題非常方便。有一次我排查本機(jī)環(huán)境發(fā)現(xiàn) Redis 一直連不上。命令行折騰了一會(huì)兒沒找到原因后來在 BrewUI 的服務(wù)日志里看到啟動(dòng)報(bào)錯(cuò)提示是 redis.conf 里某個(gè)路徑寫錯(cuò)了。我直接在配置文件里修正路徑再在 BrewUI 里點(diǎn)一下重啟按鈕服務(wù)就正常了。這個(gè)排查過程比純命令行快很多因?yàn)槿罩救肟诤椭貑?dòng)作都在同一個(gè)界面里。3.4 依賴關(guān)系可視化幫你搞懂包的層級(jí)Homebrew 的依賴關(guān)系用命令行查也能查比如brew deps --tree nginx會(huì)畫出一棵依賴樹。但說實(shí)話當(dāng)依賴層級(jí)超過三四層終端里的樹狀結(jié)構(gòu)就不太好讀了。而 BrewUI 會(huì)把依賴關(guān)系渲染成一張可視化的依賴圖父節(jié)點(diǎn)、子節(jié)點(diǎn)、共享依賴、循環(huán)依賴一眼就能看懂。這個(gè)功能至少有三個(gè)使用場景你想卸載一個(gè)包但不確定還有沒有其他包在依賴它。直接看依賴圖你會(huì)發(fā)現(xiàn)一個(gè)包被其他十幾個(gè)包共同依賴那果斷不能輕易卸載。排查環(huán)境問題時(shí)你想快速定位這個(gè)包為什么會(huì)裝進(jìn)系統(tǒng)。順著依賴樹往上看就找到了真正的源頭。評(píng)估升級(jí)影響面。某個(gè)依賴要升級(jí)你先看它會(huì)被哪些上層的包引用評(píng)估一下風(fēng)險(xiǎn)再行動(dòng)。這里我踩過一次坑有一次我清理無用的包命令行里刪掉了一個(gè)看似獨(dú)立的開發(fā)工具結(jié)果第二天發(fā)現(xiàn)另外兩個(gè)項(xiàng)目跑不起來了。去查依賴圖才懊悔那個(gè)包雖然是獨(dú)立安裝的但它提供了一些動(dòng)態(tài)庫被項(xiàng)目里的其他組件通過brew link間接引用了。所以我現(xiàn)在清理包之前必定會(huì)在 BrewUI 里先看一眼依賴關(guān)系寧可留著也不沖動(dòng)卸載。3.5 緩存分析與磁盤空間清理還有一個(gè)很多人忽略的功能是存儲(chǔ)空間分析。Homebrew 在安裝和升級(jí)過程中會(huì)在~/Library/Caches/Homebrew目錄下緩存下載的安裝包。時(shí)間長了這個(gè)目錄可能膨脹到好幾個(gè) GB。命令行清理方式是brew cleanup --pruneallBrewUI 把這一步圖形化之后你會(huì)很直觀地看到每個(gè)緩存的下載包體積是多少、一共占了多少空間點(diǎn)一下清理按鈕就完成。對于磁盤緊張的用戶這個(gè)功能非常實(shí)用。另外BrewUI 通常還能列出哪些包占用了最大磁盤空間。這個(gè)數(shù)據(jù)其實(shí)是根據(jù) formula 安裝目錄里文件大小統(tǒng)計(jì)出來的雖然統(tǒng)計(jì)過程可能需要一點(diǎn)時(shí)間但結(jié)果對我們這種經(jīng)常裝各種開發(fā)工具的人很有用。我就是靠這個(gè)功能發(fā)現(xiàn)電腦里居然裝了兩個(gè)版本的 OpenCV一個(gè)三年前的舊版本完全沒用了占了差不多 1.5GB 空間直接在 BrewUI 里卸載磁盤一下子就清爽了。4. 使用過程中常見的坑以及我的排查方案實(shí)錄4.1 問題速查表問題現(xiàn)象最常見原因我的排查思路打開 BrewUI 后包列表是空的brew 安裝目錄不在默認(rèn)位置或權(quán)限受限先執(zhí)行brew list看命令行是否正常再檢查 brew 前綴路徑安裝包失敗提示權(quán)限不足目錄歸屬不對或系統(tǒng)安全設(shè)置攔截修復(fù)目錄權(quán)限重試前先徹底退出 BrewUI 再啟動(dòng)升級(jí)后某些服務(wù)起不來新版配置格式變化查看服務(wù)日志對比新舊配置文件差異點(diǎn)擊啟動(dòng)按鈕沒有任何反應(yīng)brew services 后臺(tái)任務(wù)異常在終端執(zhí)行brew services list看是否有殘留進(jìn)程必要時(shí)brew services kill圖標(biāo)轉(zhuǎn)圈很久不刷新Homebrew 索引更新緩慢看網(wǎng)絡(luò)是否正常先執(zhí)行brew update手動(dòng)刷新顯示磁盤占用和實(shí)際不符統(tǒng)計(jì)緩存未刷新或符號(hào)鏈接干擾刷新界面必要時(shí)到安裝目錄里核對文件4.2 權(quán)限問題的深度處理如果你發(fā)現(xiàn) BrewUI 里能瀏覽但任何寫操作都失敗十有八九是目錄權(quán)限問題。除了前面提到的 chown 修復(fù)方式之外有一種更徹底的處理方法sudo rm -rf /opt/homebrew /bin/bash -c $(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)這是完全重裝 Homebrew 的方式。雖然有點(diǎn)暴力但在目錄權(quán)限徹底亂掉、修都修不回來的時(shí)候重裝反而比逐條排查更快。重裝完成之后重新打開 BrewUI 掃描基本都能恢復(fù)正常。4.3 更新索引網(wǎng)絡(luò)問題BrewUI 更新索引依賴于訪問 GitHub 倉庫。在國內(nèi)網(wǎng)絡(luò)環(huán)境里可能因?yàn)榫W(wǎng)絡(luò)延遲或連接不穩(wěn)定導(dǎo)致更新失敗。這時(shí)候不要反復(fù)點(diǎn)擊重試先到終端里手動(dòng)執(zhí)行一次brew update --verbose如果終端里也更新失敗那問題就不在 BrewUI 上而是網(wǎng)絡(luò)鏈路的問題??梢钥紤]更換或檢查網(wǎng)絡(luò)或者配置可用的鏡像源。配置鏡像源的常見方法是修改環(huán)境變量把 Homebrew 的下載地址替換為鏡像站地址之后再運(yùn)行 BrewUI 就不會(huì)卡在索引更新上。4.4 GUI 操作與終端操作混合使用的警示BrewUI 雖然提供了圖形界面但它操作的對象和你命令行操作的對象是同一個(gè) Homebrew 目錄、同一個(gè)數(shù)據(jù)庫。也就是說BrewUI 里看到的包、服務(wù)狀態(tài)和終端里brew list、brew services list查出來的狀態(tài)必須始終一致。大多數(shù)時(shí)候確實(shí)一致但有一個(gè)坑如果你在終端里手動(dòng)安裝或卸載了某個(gè)包而 BrewUI 還開著它不會(huì)實(shí)時(shí)感知這個(gè)變化列表會(huì)顯示過期信息。這時(shí)候需要手動(dòng)刷新如果刷新后還是舊信息就重啟一次 BrewUI。反過來也一樣。在 BrewUI 里做操作時(shí)終端里正在跑的brew命令可能會(huì)導(dǎo)致索引沖突。以前我遇到過同時(shí)用 BrewUI 更新一個(gè)包又在終端里手動(dòng)卸載另一個(gè)包結(jié)果兩個(gè)操作報(bào)錯(cuò)日志顯示是 brew 的鎖文件沖突。所以我的建議很簡單同一時(shí)間只從一個(gè)入口操作 Homebrew不要兩個(gè)入口同時(shí)動(dòng)。5. 我對 BrewUI 的真實(shí)使用心得和一些延伸想法用了幾個(gè)月下來說實(shí)話我已經(jīng)回不到純命令行管理 Homebrew 的狀態(tài)了。原因不是命令行不好用而是 BrewUI 幫我解決了知曉的問題。以前我管理 brew 包多少有點(diǎn)黑箱的感覺知道自己裝了什么但不清楚它們之間的關(guān)聯(lián)、狀態(tài)、變動(dòng)趨勢。BrewUI 把整個(gè)系統(tǒng)變成了一張可以隨時(shí)查看的地圖雖然地圖上的很多操作最終還是要通過底層的 brew 命令來完成但至少我看得見全局心里有數(shù)了。給不同階段的讀者一個(gè)建議如果你是剛接觸 Homebrew 的新手建議不要一上來就完全依賴 BrewUI。你至少要能看懂終端里brew install、brew list、brew services這三組命令的輸出理解一下日志的含義。這樣你在圖形界面里碰到問題時(shí)才知道怎么去排查。圖形界面是讓你用得更舒服不是讓你完全脫離對底層邏輯的理解。如果你已經(jīng)用了很多年 brew可以試試用 BrewUI 做一次環(huán)境體檢??纯醋约簷C(jī)器上到底堆了多少舊緩存、多少無用的包依賴、多少開著卻很久沒用過的服務(wù)。很多時(shí)候你清理完那一輪本機(jī)環(huán)境都會(huì)輕松不少。如果以后繼續(xù)擴(kuò)展BrewUI 這類工具也許還能把多臺(tái)機(jī)器的軟件環(huán)境對比做出來。我現(xiàn)在維護(hù)的機(jī)器有兩臺(tái)一臺(tái)日常開發(fā)一臺(tái)跑一些常駐任務(wù)軟件清單有差異但靠眼睛去對比兩個(gè) brew list 的輸出很費(fèi)勁。如果 BrewUI 能支持導(dǎo)出和對比環(huán)境清單那對有多臺(tái)設(shè)備的人來說會(huì)更方便。最后的體會(huì)落回一句話工具永遠(yuǎn)是為你服務(wù)的關(guān)鍵是你自己要對工具背后發(fā)生了什么有判斷力。BrewUI 很好用但它讓我更愿意去理解 brew 本身這大概才是它帶給我的最大價(jià)值。