12

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???

5
  • /etc/profile ? Commented Dec 2, 2015 at 3:39
  • not an answer, but you can add a PATH= line to .zshrc Commented Dec 2, 2015 at 4:02
  • 1
    It could be inherited from the terminal that started zsh, which in turn gets it from wherever OSX paths are usually set.
    – muru
    Commented Dec 2, 2015 at 7:37
  • stackoverflow.com/questions/9832770/…
    – llua
    Commented Dec 5, 2015 at 4:34
  • You can use -xl option as this says.
    – An5Drama
    Commented Apr 19 at 0:25

2 Answers 2

23

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.

2
  • in ubuntu 20.04 the system-wide zsh config files (eg. zprofile zshenv) are inside /etc/zsh. but this response is still helpful
    – yaitloutou
    Commented Jul 11, 2020 at 22:28
  • 2
    It's specifically about how it works on macOS so it shouldn't be too surprising that Ubuntu does things differently.
    – Alan Third
    Commented Aug 3, 2020 at 13:00
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.

8
  • I gave you a point, however could you elaborate more it please? Commented Dec 2, 2015 at 8:10
  • @RuiFRibeiro answer updated. Commented Dec 2, 2015 at 8:43
  • Hmm. If that's the case, why does PATH= /usr/bin/zsh -c 'echo $PATH' print nothing for me?
    – muru
    Commented Dec 2, 2015 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. Commented Dec 2, 2015 at 8:55
  • What does that command print for you, with empty zshenv files?
    – muru
    Commented Dec 2, 2015 at 8:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .