AI 與 自動化 2026年4月27日

2026 OpenClaw PATH、Homebrew 前綴,以及 launchd 下 ProxyMac Mac mini 的 MCP 可執行失敗

ProxyMac 工程團隊 2026年4月27日 約 12 分鐘閱讀

香港、日本、韓國、新加坡或美國的租用 Mac mini M4 上跑 OpenClaw 時,團隊常把日誌裡 env: node: No such file or directoryuvx: command not found 整段貼過來,可同一指令在 終端機 裡明明成功。本文是登入 shell 與 launchd 之間的 PATH 契約:講清 Apple 晶片上 brew --prefix 為何不同、如何不猜就讀 LaunchAgent plist,並給出與 MCP 佈建上線除錯安裝與上線 能接上的五步驗證階梯。你會看到一張與 Wi‑Fi 文風格不同的三欄表、可在簽核後貼上的 EnvironmentVariables 片段、以及面向 說明OpenClaw 專題 的按鈕。若你來自混合機型筆電艦隊,還請在工單寫清是 arm64 還是 x86_64 解譯器,避免把 Rosetta 指錯當成「OpenClaw 壞掉」;也建議在變更窗前先以唯讀域列印 launchctl,免誤把別人的 GUI 域當成系統域。若週期性滾版會帶到 brew 升級,記得在變更單上勾「PATH 不變」的驗收項,讓 SRE 不用靠猜釘死責任歸屬。

再補三條實務邊界:第一,sudo -issh 非互動工作階段各自繼承的環境並不相同,別拿 root 的 echo $PATH 去判 launchd 子程序。第二,若 OpenClaw 以 LaunchDaemon 跑在 daemon 域,gui/$(id -u) 裡看到的 PATH 完全無關,應改查對應 bootstrap 與 plist 的 ProgramArguments 是否多包了一層 env。第三,Node 透過 #!/usr/bin/env node 解析時,缺的是 env 的解析路徑,而不只是 node 本體,記得把 /usr/bin 留在字串裡。把上述備註附在回復原單上,能顯著減少「我筆電 OK」類來回,尤其在港日星美韓 多區平行放量時。若 CI 在 macOS 13 與 15 上同時驗過,也請在表頭標最低支援版本,避免老映像把 PATH 又洗回舊式 /usr/local 優先。若你使用 asdf 或 nvm 之類工具,額外確認 LaunchAgent 不會吃到互動式初始化腳本——那些只在終端登入時執行。

終端機對 launchd:兩套宇宙

macOS 下互動式 shell 會跑 /etc/zprofile~/.zprofile~/.zshrc,常含 eval "$(/opt/homebrew/bin/brew shellenv)"launchd 代理拿到的是偏保守環境:PATH 常落在 /usr/bin:/bin:/usr/sbin:/sbin 這一檔,除非 plist 裡加長。網關建立 MCP 子程序時,於是活在被裁切的宇宙裡,npxpnpm 墊片根本不存在,儘管終端機裡 which npx 會印 /opt/homebrew/bin/npx。不是「OpenClaw 把 MCP 弄丟」——execve 回傳 ENOENT,核心解析不到 shebang 或解譯器路徑。把問題定對,排錯常可以快一個量級,也不會誤闖 stdio 緩衝那篇;PATH 沒對齊前先把可執行修掉,再談管線。若你曾用 GUI 的「在終端機打開」驗路徑,也請在文件註明那是人的脈絡,以免自動化團隊照抄到 plist。遇見「僅週末批次失敗」這種間歇案,別急著怪 cron——多半是維護窗裡有人 brew upgrade 換了軟連順序,用雜湊對拍能在一分鐘內結案。另若 mini 上同時開 Docker Desktop,有時會把 docker 的 CLI 也塞進爭用同一段 PATH 的自動更新腳本,記得在問題描述裡明寫「實體機直跑」還是「在容器裡跑 OpenClaw」,不要混成一句。

  • 先證明裂口:在一槍式 ssh mini 'launchctl print gui/…' 裡記 printenv PATH,與登入 shell 比對。
  • 外層 MCP 二進位優先用絕對路徑,同時把附手工具的 PATH 穩下來。
  • 在 Git 裡跟漂移:設定版控 模式留快照,系統升級時 brew 根目錄別悄悄變臉。
別拿圖形工作階段的 PATH 當無人值守真值。螢幕共享與 LaunchAgent 的環境表可不同——用 VNC 聯調是的脈絡,不是自動化的地契。

Apple 晶片與 Intel:Homebrew 前綴矩陣(與 Wi‑Fi 文不同的三欄表)

機器代際預設 brew 前綴缺 PATH 時的典型症狀
Apple 晶片 M4 Mac mini/opt/homebrewnode 找不到,可 /opt/homebrew/bin/node -v 仍出 v22.x
Intel Mac mini(舊機)/usr/localMCP JSON 仍指從筆電抄來的 /opt/homebrew/bin/uvx
混編裝置隊磁碟上兩套都有PATH 把 /usr/local/bin 放在 /opt/homebrew/bin 前時,錯的 shim 先中獎

能扛重開機的 plist EnvironmentVariables 模式

在託管 OpenClaw 或 MCP 督導行程的 LaunchAgent 裡加 EnvironmentVariables 字典。順序有學問:先 Homebrew 墊片,再系統路徑,後接 ~/.local/bin 之類的語言工具鏈。改完走 launchctl bootout gui/$(id -u)/…kickstart;在 macOS 14 以後單靠舊式 unload 往往不牢靠。與 監控指南 的探活併在一起,可在 PATH 抽風後約三分鐘內觸發告警。若你放在團隊共用的 LaunchDaemon,記得用合適的 bootstrap 域並在文件寫回復原步驟,免半套 PATH 在凌晨滾式發佈裡灑到港日星美韓 全艦隊。變更窗結束前跑一筆 launchctl print 歸檔,年底稽核要調閱也拿得出。若你由 MDM 統一下發描述檔,別忘「覆寫層」會先於你手動改過的 LaunchAgent 合併環境——此時以 MDM 宣告為準,工單要寫裝置序號與描述檔版號,別只貼本機 plutil -p 片段。多使用者共用的實驗機上,gui/501gui/502 的 PATH 也會分岔,重演問題時要鎖定同一 UID。最後,LaunchAgent 以登入使用者執行,LaunchDaemon 以 root 執行,混用時 OpenClaw 與 MCP 子程序落哪一側務必一開始就定案,別半夜把 GUI 域 plist 指到屬於系統域的路徑。

範例片段(正式上線前再驗證)

<key>EnvironmentVariables</key> <dict> <key>PATH</key> <string>/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string> </dict>

安全註記:加寬 PATH 比關 SIP 或關 Gatekeeper 正常得多。仍避免把整顆可寫入目錄頂在 PATH 最前——使用者可寫二進位與 金鑰衛生 一起送審。

整份改寫 MCP 之前五項檢查

  1. 雜湊比對:在終端機對 shasum -a 256 $(which uvx),與即將寫進 MCP JSON 的絕對路徑對拍。
  2. 倒出 launchd 環境:launchctl print user/$(id -u)/limit 與代理域確認 PATH 真載入。
  3. 模擬非登入:env -i PATH=/usr/bin:/bin /opt/homebrew/bin/npx --version 看極小 PATH 下 npx 自己能否活。
  4. 對 JSONL:JSONL 診斷 裡篩 ENOENT
  5. 留可還原快照:升級還原 在大量改 PATH 前逐台 plist 下標籤。

Node、uv 與墊片:版本管理在 launchd 下為何會爆

開發者常用 fnmmiseasdf 在諸多儲庫之間切換多版本 Node,而這些工具幾乎總在 ~/.zshrc 裡改 PATHlaunchd 卻不會讀。MCP 寫 npx @scope/server 時,npx 本體必須先以絕對路徑能被執行,之後才會再碰 ~/.npm 等快取。把筆電貼上來的 JSON 裝到 全新 ProxyMac mini,很典型是:互動式 shell 裡 corepack enablepnpmPATH 裡,plist 仍讓 shebang 走 /usr/bin/env node,結果命中系統殘件(部分映像為 v18),與鎖檔假定的 v22 不一致。落差往往不會變成整行「找不到執行檔」,而埋在 OpenClaw 重試裡,以 ERR_PNPM_UNSUPPORTED_ENGINE 之類難讀字樣出現。

uv 同理:uvx 經 curl 裝好後常在 ~/.local/bin~/.cargo/bin,就算終端機能跑,launchdPATH 仍常缺那些目錄。與其在 plist 再疊一長串,不如放一支精簡包裝腳本/usr/local/bin/mcp-env.shroot:wheel、不要設成眾人可寫),在腳本裡一次匯出 PATHexec 真正入口——稽核寧可審一個可 diff 的檔。把腳本與 閘道 launchctl 重啟與復原 用片段一樣納 Git,週二與週四放量之間才能對上改了什麼。

執行環境人常裝在這未修補時 launchd 實際看到
經 Homebrew 的 Node/opt/homebrew/bin/node多停在 /usr/bin/env 解析;沒有 brew 墊片就 ENOENT
uv 工具鏈~/.local/bin/uvxplist 字串裡的波浪不會自己展開,除非你先處理
經 Corepack 的 pnpmnode 同目錄的墊片只有該目錄在 PATH 裡排 /usr/bin 前面才一致
營運提示: 加一支冒煙用 LaunchAgent,每 15 分鐘/opt/homebrew/bin/node -e "console.log(process.version)",把標準輸出那行併入 JSONL 管線;brew 升級換掉二進位時,版號會先跳,用戶端往往還沒察覺。

常見問題

要不用 /bin/zsh -lc 包一切? 能跑,但會藏錯、也打亂信號處理——PATH 能顯式就別繞登入函式。

Rosetta 的 brew 會搞掛 MCP 嗎? 當二進位是 x86_64 而代理以 arm64 建出來時會——用 file $(which node) 對拍架構與 OpenClaw 建置。

stdio 還卡? PATH 管執行前的解析;執行後是管線——若行程已起來還是掛,讀 stdio 緩衝

為何 ProxyMac Mac mini 適合把 PATH 合約凍住

專用 Mac mini M4 給每租戶自己的金屬邊界:一旦 /opt/homebrew 驗過,就躺在 NVMe 上挨著你的 OpenClaw 工作區,別的工程師不會隨手 brew uninstall 共用 CI 可執行檔。原生 arm64 二進位少踩 Rosetta,統一記憶體 讓平行 MCP 工作者少爭 NUMA,五個區域 可在法遵近處佈副本、Git 裡 plist 卻保持同一份。PATH 變乏味之後,用 平行代理 提併發,在 定價 約節點,讓人走 說明中心,GUI 提示必須人工點時再看 VNC 文件。把三個連結放進值勤手冊首頁,能少一半被誤報成「機房不對」的徹夜。若你還有合規審 log,也請把 launchctl print 的時間戳一併附給稽核,省得年後被問「那時到底哪個 PATH 生效」卻沒有證物。對要稽核的團隊,還可把「PATH 與 plist shasum」當成季節性健康檢查項,與 金鑰衛生 的輪替節奏對齊。若未來遷到可重複的 Ansible 或 Nix 層,記得仍保留 launchd 為事實來源,否則抽象層一升級又會出現「能跑但沒人知道為何能跑」的隱性負債。

PATH 定一次,到處跑 OpenClaw

港日星美韓 · Apple 晶片 M4