purcell / exec-path-from-shell

Make Emacs use the $PATH set up by the user's shell
Other
1.43k stars 82 forks source link

Issues with zsh on macOS #91

Closed gpanders closed 5 years ago

gpanders commented 5 years ago

First let me say I know there are a few open issues with titles similar to mine, but I didn't see my particular question addressed in any of those.

I am following the recommended advice and putting all of my PATH setup in my ~/.zshenv and removed the -i and -l flags from exec-path-from-shell-arguments. In Emacs, this all works fine.

However, this causes problem when I use my terminal emulator, which does act as a login shell. In macOS the default /etc/zprofile file calls a program called path_helper that modifies your path in login shells by reading paths from /etc/paths and /etc/paths.d. Because I set up my PATH in .zshenv (which is sourced before /etc/zprofile and .zprofile) my path gets messed up. Here's a (minimal) example of what I mean:

.zshenv:

# Add /usr/local/bin to PATH for Homebrew packages
export path=(/usr/local/bin /usr/bin /bin /usr/local/sbin /usr/sbin /sbin)

# Add pyenv to path
export path=($HOME/.pyenv/bin $path)

/etc/paths:

/usr/bin
/bin
/usr/sbin
/sbin
  1. At the end of .zshenv, my path is $HOME/.pyenv/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin
  2. /etc/zprofile is sourced, which calls /usr/libexec/path_helper, which reads /etc/paths and changes my PATH to /usr/bin:/bin:/usr/sbin:/sbin:$HOME/.pyenv/bin:/usr/local/bin
  3. .zprofile is sourced, but because I removed all PATH modification into .zshenv, no further changes happen

Now, /usr/bin is first in my path ahead of both pyenv and /usr/local/bin, which is obviously not what I want (since my installed packages are shadowed by the macOS default binaries).

The easy solution would be to do all of my PATH setup in .zprofile so that it happens after path_helper is called. But then that would violate the recommendations of this plugin.

Since I know you also use zsh and I think you also use macOS(?), I'm wondering how you handle this.

purcell commented 5 years ago

Yep, my setup is:

The easy solution would be to do all of my PATH setup in .zprofile so that it happens after path_helper is called. But then that would violate the recommendations of this plugin.

I suspect that I should stop recommending any particular scheme or "ideal" for the startup files. I even thought about removing the warning recently. While there are reasons to avoid -l and -i, most notably the shell startup time and incidental terminal output, I think most people just don't care, and simply want the PATH that comes with -l + -i.

gpanders commented 5 years ago

In fairness it's not just your recommendation but I think it is even the recommendation of zsh that PATH manipulation should go in .zshenv. Unfortunately, most distributions (macOS included) seem to not honor the intended usage of the zsh/bash init file hierarchy.

Thanks for the quick reply. I'll go ahead and close this since it seems like there isn't really a "right" answer here.

purcell commented 5 years ago

Yup. FWIW, setting the full path explicitly has been pretty foolproof for me. And note that I imaging you can always call path_helper yourself at any convenient point.