読者です 読者をやめる 読者になる 読者になる

zsh5.0.5を入れたら、PATHがおかしくなった

homebrewで入れたzsh5.0.5で、pingやtraceroute, netstat, ipconfigといったコマンドを使おうとしたら、以下のように、コマンドが使えなくなっていました。

$ ping
zsh: command not found: ping

いやそんなはずはない…と思ったのですが、ターミナルを立ち上げなおしても100%再現するので、原因を調べてみました。

$ whereis ping
/sbin/ping
$ /sbin/ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
...

コマンド自体はなくなっていないようで、コマンドを絶対パスで指定して実行すると、ちゃんと動作します。
ということは、PATHが通っていないのでは?と思い、PATHを確認してみましたが、やはり通っていませんでした。

原因

通常zshは一番はじめに/etc/zshenvを読みにいくようです。
zshでログイン・ログアウト時に実行されるファイル - Qiita [キータ]
/etc/zshenvの中身をみてみると、

if [ -x /usr/libexec/path_helper ]; then
     eval `/usr/libexec/path_helper -s`
fi 

と書かれています。
path_helperというのは、OSXで「/etc/pathsおよび/etc/paths.dからPATHを作り出し、元からあったPATHから重複を除いたものを後ろにつける」というプログラムです。要するにデフォルトのPATHを設定してくれるようです。
hayajoのTumblr, OSXでのzshにおけるPATH設定
今まではこのプログラムがzshを立ち上げる時に実行されることで、/sbinや/usr/sbin等にPATHを通していました。
しかし、zsh5.0.4からデフォルトの挙動が変わり、path_helperは呼ばれなくなりました。このせいで今回のような事が起きました。
この変更に関しての議論はこちらです。
Minor confusion in zsh install warning · Issue #24538 · Homebrew/homebrew · GitHub
Appleの/etc/zshenvのデフォルト設定が不適切なのでデフォルトで無効になるようにしようということだそうです。

解決方法

  1. インストール時にオプションとして、--enable-etcdirを付加すれば今までどおり/etc以下の設定ファイルも読んでくれるようです。
$ brew install zsh --enable-etcdir
  1. もしくは、ホームディレクトリの.zshrcにpath_helperの実行結果を追記しておきます。
p=$PATH;PATH=;/usr/libexec/path_helper -s >> ~/.zprofile;PATH=$p