6

I'm using zsh 5.0.8 version in iterm2 on OSX.

I start my computer and printenv shows me the $PATH variable:

/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/git/bin

from my understanding, zsh will source the following file in order:

/etc/zshenv
~/.zshenv
/etc/zshrc
~/.zshrc

I checked, I don't have the first 3 files, and my .zshrc is basically empty, nothing related to the $PATH variable.

Then where is the $PATH variable set???

12

I literally just had a battle with this today.

On OS X Yosemite PATH is built up in a rather roundabout way.

I believe that, as cremefraiche says, ZSH has a built-in $PATH that it uses if nothing else is set, but that's not where yours is coming from. First of all there is a file, /etc/paths, that contains a list of directories. There is also a directory, /etc/path.d that contains more files that contain directories. The program /usr/libexec/path_helper takes these lists of directories, merges them with the existing $PATH variable (if there is one), removes any duplicates, and outputs the result, with the /etc/paths directories listed first.

You can try running it yourself, it doesn't do any harm. Here's the output from mine:

$ /usr/libexec/path_helper 
PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/local/MacGPG2/bin:/Users/alan/.local/bin:/Users/alan/src/go/bin"; export PATH;

On it's own, this doesn't do anything, but it's called from, on my machine, /etc/zprofile:

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

This might vary on your machine, as it seems Apple have moved this code around a bit in different versions of OS X.

Here's the list of all the files that ZSH reads in OS X, in the order they are evaluated:

  1. /etc/zshenv
  2. ~/.zshenv
  3. /etc/zprofile
  4. ~/.zprofile
  5. /etc/zshrc
  6. ~/.zshrc
  7. /etc/zlogin
  8. ~/.zlogin
  9. ~/.zlogout
  10. /etc/zlogout

Some of these files aren't evaluated in certain circumstances, like when run as non-interactive shell scripts, but I'm not going to discuss that here. It's in the ZSH man page if you're interested.

$ man zsh

It's worth noting that /etc/zprofile is run after ~/.zshenv, so if you follow the ZSH guidelines and set your $PATH in .zshenv, it's probably going to be clobbered by path_helper. If you're running into this problem it might be worth renaming /etc/zprofile as /etc/zshenv so the system $PATH will be set as early as possible.

1

This refers to bash, but I suspect is applicable to zsh as well.

The default value of PATH is determined when bash is compiled. It is not set in a startup file, although it might be modified there.

A Practical Guide to Fedora and Red Hat Enterprise Linux: Seventh Edition. p359.

Edit

I did some more digging and found that the default PATH is in fact set during compilation, and can be found in the init.c file.

/* Set default path */
path    = (char **) zalloc(sizeof(*path) * 5);
path[0] = ztrdup("/bin");
path[1] = ztrdup("/usr/bin");
path[2] = ztrdup("/usr/ucb");
path[3] = ztrdup("/usr/local/bin");
path[4] = NULL;

EDIT2:

I went into zsh IRC on freenode, and a dev was able to give me a list of four different commands that all demonstrate that the PATH is set in compilation. I posted these commands in the extended chat, but did not realize they would be lost after X amount of time. Ask devs in IRC to demonstrate if you would like to see for yourself.

  • I gave you a point, however could you elaborate more it please? – Rui F Ribeiro Dec 2 '15 at 8:10
  • @RuiFRibeiro answer updated. – cremefraiche Dec 2 '15 at 8:43
  • Hmm. If that's the case, why does PATH= /usr/bin/zsh -c 'echo $PATH' print nothing for me? – muru Dec 2 '15 at 8:50
  • @muru I don't understand why it would. I just said what is in the book then found where it is set in source. – cremefraiche Dec 2 '15 at 8:55
  • What does that command print for you, with empty zshenv files? – muru Dec 2 '15 at 8:56

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.