17

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.
path=(
  ~/Library/Haskell/bin
  /usr/local/{bin,sbin}
  $path
)

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's what's controlling where cabal is being loaded from.

UPDATE: Running echo $SHELL from Emacs prints: /bin/zsh

UPDATE 2: This is on OSX.

UPDATE 3: I have tried to use exec-path-from-shell module and it does not work. I still have same issues, and as a side effect, it messes up my terminal theme colours :(

UPDATE 4: I've installed Emacs via brew install --cocoa --srgb emacs and I run emacs that's linked this way:

~ ❯❯❯ which emacs
/usr/local/bin/emacs
~ ❯❯❯ l /usr/local/bin/emacs
lrwxr-xr-x  1 g  admin    30B 29 Jan 18:34 /usr/local/bin/emacs -> ../Cellar/emacs/24.4/bin/emacs
~ ❯❯❯ l /usr/local/Cellar/emacs/24.4/bin/emacs
-r-xr-xr-x  1 g  admin    87B 29 Jan 18:34 /usr/local/Cellar/emacs/24.4/bin/emacs
  • Are you using ZSH as your login shell? – wasamasa Apr 16 '15 at 16:36
  • Not sure what you mean by login shell exactly, but I guess I called chsh... back in the day to change my default shell – Galder Zamarreño Apr 16 '15 at 16:46
  • I'm using iTerm2 btw... – Galder Zamarreño Apr 16 '15 at 16:47
  • 2
    Apparently not, modify PATH in ~/.profile or /etc/profile then. – wasamasa Apr 16 '15 at 17:23
  • 1
    Set your environment variables in ~/.zshenv, which will be consistently sourced however the shell is started (interactive vs. non-interactive). If exec-path-from-shell is messing up your terminal theme colours, you can set exec-path-from-shell-arguments to nil before calling exec-path-from-shell-initialize to make sure it's not running the interactive parts of your zsh config. – sanityinc Apr 18 '15 at 10:48
11

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

(exec-path-from-shell-initialize)
  • 1
    The question would be better with a link to the cited package. – Drew Apr 17 '15 at 14:15
  • You're right, I've just edited my answer. – Basak Apr 18 '15 at 14:58
  • This is all I ever wanted. – djhaskin987 Jan 20 '17 at 23:21
8

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 1.22.2.0 :D

Thanks all!!

  • Thanks to beOn for his hints in this $PATH on OSX post. – Galder Zamarreño Apr 17 '15 at 7:18
  • 2
    A better solution is to modify path in ~/.zshenv. Changes there are reflected in Emacs' PATH – Galder Zamarreño Apr 24 '15 at 15:57
  • I can confirm that simply doing echo export PATH=$PATH > ~/.zshenv makes Emacs' M-x shell pick it up on the next invocation. – Linus Arver Aug 16 '16 at 21:35
5

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:

https://help.ubuntu.com/community/EnvironmentVariables#Session-wide_environment_variables

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 environment. How you set up the $PATH for the GUI seems to depend on the OS version. However you can use:

(setenv "PATH" (concat (getenv "PATH") ":/foo/bar"))

in your ~/.emacs.d/init if you just want a solution that should work.

PPS: If you want to run a shell in emacs, you are probably better off using ansi-term rather than shell.

  • I doubt the question is about Linux given the questioner mentioned the use of iTerm 2. – wasamasa Apr 16 '15 at 22:39
3

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.

2

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.

  • 1
    This works for a shell run under Emacs. It does not work for commands run directly within Emacs, such as via M-x shell-command. – mernst Jul 30 '18 at 18:41
1

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:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>my.startup</string>
  <key>ProgramArguments</key>
  <array>
    <string>sh</string>
    <string>-c</string>
    <string>launchctl setenv PATH /usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
</dict>
</plist>

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 remove them.

In 10.9 and earlier you can also add a line like this to /etc/launchd.conf:

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

However support for /etc/launchd.conf was removed in 10.10.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.