I use a mac. If I open a terminal and run echo $PATH I get the current "PATH" variable in my environment. If I add something to my path or to my other environment variables, it only persists for as long as that process is alive.

What I want to know is, how did this path get the values it has by default? I looked in my .zshrc (or .bash* if I were using bash) but there's nothing there that exports all programs that are on the path. What is it about the OS the controls this default PATH list?


login(1) traditionally set PATH before turning things over to the shell, though you may need to think differently on OS X, as there's also ~/.MacOSX/environment.plist where such can be set (probably not recommended to use, unless it's necessary for some special application), and last I checked Apple was adding a path_helper(8) command to muss with PATH in global shell rc files under /etc.

For ZSH on Mac OS X I disable path_helper and set PATH manually only in my ~/.zshenv file. This may not be ideal if you actually need something under a path set by path_helper.


The link that @corleone posted shows how the $PATH environment variable gets interpreted.

The reason why it does not persist when you declare it in the terminal is because that is a temporary process that will eventually exit. The variable has to get set from a file that is sourced when the shell is launched, which will normally be one of your dotfiles.

Unlike many operating systems, OS X does not automatically include a .profile or .bashrc in users' home directories, but instead defaults to .bash_profile, which will be evaluated last if you do create a .profile or .bashrc (which will also be evaluated).

If you want to update your $PATH to include specific directories, the best place to put it (on OS X) would be in your .bash_profile, which will take precedence over any other locations that set that particular variable. If you don't want to overwrite anything, but just want to add something, in your .bash_profile, you could include a line like this:


On shell startup, /etc/profile runs /usr/libexec/path_helper, and the output of that command is evaled to set the initial value of the path. See man path_helper to see how this program gets the initial list of directories to put in its output.


The loginwindow.app is responsible for setting up the initial environment for a user. The loginwindow.app passes off the authentication process and when the user is authenticated the environment is setup as if login -pf USERNAME is called (read man login and man environ). At this point the PATH is /usr/bin:/bin:/usr/sbin:/sbin the same as user.cs_path = /usr/bin:/bin:/usr/sbin:/sbin set in the kernel. I should mention that this is all run by root and if you are using a GUI session, there is no shell.

The Terminal.app will start your shell as a login shell by default. login -pf USERNAME is run (as root) and then the shell's rc files are read. For bash and ksh, /private/etc/profile is read. Forzsh,/private/etc/zshenvis read. Forcsh,/private/etc/csh.loginis read. All use/usr/libexec/path_helper to modify the PATH set by theloginwindow.app`.

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.