1

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?

4 Answers4

2

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.

thrig
  • 34,938
1

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:

PATH="$PATH:/path/to/another/bin"
rubynorails
  • 2,293
0

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`.

fd0
  • 1,449
0

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.

chepner
  • 7,501