Emacs and command line $PATH disagreements on OSX

2018-05-16 16:57:41

Having some issues with PATH settings on Emacs that are affecting my Haskell environment:

I'm using ZSH, and when I go to the command line and call echo $PATH, it returns: /Users/g/Library/Haskell/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin

This is coming from .zprofile configuration where I have:

# Set the list of directories that Zsh searches for programs.






So, from command line, when I call which cabal, I correctly get: /Users/g/Library/Haskell/bin/cabal

When I start Emacs and go to the shell and call which cabal, I get: /usr/bin/cabal which is causing me issue since it's a different version.

When I inspect echo $PATH from the Emacs shell, I see: /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/g/Library/Haskell/bin:/usr/local/sbin

I've no idea how on earth the PATH can be different...

Anyone knows how to get my ZSH shell and Emacs to agree on the same PATH? I suspect that'

  • You can also install exec-path-from-shell package and add this to your init file:


    2018-05-16 17:03:01
  • This is an OSX annoying environment issue, the $PATH appearing in Emacs is coming from /etc/paths file, which then gets appended with whatever I've set in the shell. I added /Users/g/Library/Haskell/bin to the top of the /etc/paths file and it then worked fine.

    Going into shell and calling echo $PATH in Emacs shows now: /Users/g/Library/Haskell/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/sbin

    And cabal's version is indeed cabal-install version :D

    Thanks all!!

    2018-05-16 17:30:06
  • If you start emacs from your GUI environment (gnome, kde, ...) your shell startup scripts will not be sourced into your environment. So the $PATH that you carefully set in your .zsh will not be loaded. GUI environments do not generally source these, though they may load your ~/.profile file.

    You can try adding this to your .pam_environment:

    PATH DEFAULT=${PATH}:/MYHOMEDIR/Library/Haskell/bin:/usr/local/bin:/usr/local/sbin

    You will need to restart your GUI session to load it.

    This document might help you to get your $PATH variable set properly:


    I use the ~/.pam_environment file to managed environment variables that I need to be accessible from my shell or emacs processes.

    PS: An astute commenter points out that you are probably on Mac. I don't know how to set up your $PATH in the Mac GUI, but the point still stands regarding the difference between your shell's environment and the GUI envir

    2018-05-16 17:44:37
  • If some part of the PATH gets lost then you can add it in your ~/.emacs

    ;;; We add /path/to/something/extra by appending it to the path

    (setenv "PATH" (concat (getenv "PATH") ":/path/to/something/extra"))

    ;;; /path/to/something/extra is now at the end of the PATH.

    ;;; or you can use:

    ;(setenv "PATH" (concat "/path/to/something/extra:" (getenv "PATH")))

    ;;; /path/to/something/extra is now at the beginning of the PATH.

    To avoid PATH issues, I always start emacs from the command line with the PATH exported from ~/.bashrc.

    2018-05-16 18:02:35
  • You can also set an OS X-wide default path by for example saving a property list like this as ~/Library/LaunchAgents/my.startup.plist:






    launchctl setenv PATH /usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin


    The new path should be shown in shells, Emacs, and other applications after you log out and back in.

    This method does not change the path in applications that are opened as login items or when applications are reopened at login after a forced shutdown. If you have Emacs, a terminal application, or other applications where you want to change the path in login items, you'll have to re

    2018-05-16 18:28:09
  • Another way to accomplish this is to simply tell the shell that it's a login shell so that it sources all of the right files. I do this for bash by setting explicit-bash-args to ("--noediting" "--login"). It looks like the equivalent for zsh would be to set explicit-zsh-args to ("-l").

    So in my .emacs:

    (setq explicit-bash-args '("--noediting" "--login"))

    In yours, something like:

    (setq explicit-zsh-args '("-l"))

    I think the "--noediting" is unnecessary, and there doesn't seem to be a way to tell zsh about this, but that might be something to investigate if this doesn't work as well as you'd hope.

    2018-05-16 18:49:31