Mac OSX 的 PATH 設定與 path_helper

這兩天幫一台舊機器升級開發環境,包含了 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 loginInteractive non-loginScript
/etc/zshenvAAA
~/.zshenvBBB
/etc/zprofileC
~/.zprofileD
/etc/zshrcEC
~/.zshrcFD
/etc/zloginG
~/.zloginH
~/.zlogoutI
/etc/zlogoutJ

而我沒有 /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 提供的工具,用來設定 PATHMANPATH 兩個環境變數。它會先載入 /etc/paths/etc/manpaths,然後再載入 /etc/paths.d/etc/manpaths.d,而我的 /etc/paths.d 中,/usr/local/bin 被放到了最後一行,改到第一行之後就一切正常了。

Contents

comments powered by Disqus