這兩天幫一台舊機器升級開發環境,包含了 rvm,homebrew 等,在用 brew doctor
想確認一下有沒有什麼問題的時候,跳出了一個警告如下:
Warning: /usr/bin occurs before /usr/local/bin
This means that system-provided programs will be used instead of those
provided by Homebrew. The following tools exist at both paths:
git
git-cvsserver
git-receive-pack
git-shell
git-upload-archive
git-upload-pack
Consider setting your PATH so that /usr/local/bin
occurs before /usr/bin. Here is a one-liner:
echo 'export PATH="/usr/local/bin:$PATH"' >> ~/.zshrc
簡單說就是在我的 PATH
環境變數中,/usr/local/bin
被放到 /usr/bin
之後,所以我另外安裝的新版工具不會被呼叫到,而是會執行到系統自己帶的舊版工具。
因為我用的是 zsh,所以來檢查一下 ~/.zshrc
,雖然裡面有對 PATH
做設定,不過並沒有包含到 /usr/local/bin
和 /usr/bin
等路徑的設定。試著在 ~/.zshrc
檔案的一開頭加了一行 echo $PATH
,發現在 ~/.zshrc
載入之前 PATH
就已經有值了…一定是在更早的地方就被設定了。
找了一下,zsh 載入設定檔的順序如下:(Source)
Interactive login | Interactive non-login | Script | |
---|---|---|---|
/etc/zshenv | A | A | A |
~/.zshenv | B | B | B |
/etc/zprofile | C | ||
~/.zprofile | D | ||
/etc/zshrc | E | C | |
~/.zshrc | F | D | |
/etc/zlogin | G | ||
~/.zlogin | H | ||
~/.zlogout | I | ||
/etc/zlogout | J |
而我沒有 /etc/zshenv
,也沒有 ~/.zshenv
,接下來的 /etc/zprofile
內容則是:
# system-wide environment settings for zsh(1)
if [ -x /usr/libexec/path_helper ]; then
eval `/usr/libexec/path_helper -s`
fi
實際執行 /usr/libexec/path_helper
的輸出如下:
PATH="/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/local/bin"; export PATH;
MANPATH="/usr/share/man:/usr/local/share/man:/opt/X11/share/man:/Applications/Xcode.app/Contents/Developer/usr/share/man:/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/share/man"; export MANPATH;
Bingo!找到是那邊設定造成問題了。
搜尋一下,path_helper
是 OSX 提供的工具,用來設定 PATH
和 MANPATH
兩個環境變數。它會先載入 /etc/paths
和 /etc/manpaths
,然後再載入 /etc/paths.d
和 /etc/manpaths.d
,而我的 /etc/paths.d
中,/usr/local/bin
被放到了最後一行,改到第一行之後就一切正常了。