How does Mac OS X set the value of $PATH?
Usually, your PATH is set by the shell. For Bash, everything is explained in the manual. You can also open man bash
and skip to the INVOCATION
part.
Invoked as an interactive login shell, or with --login
When Bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable.
Invoked as an interactive non-login shell
When an interactive shell that is not a login shell is started, Bash reads and executes commands from ~/.bashrc, if that file exists. In OS X, additionally, there is
path_helper
which reads the contents of/etc/paths.d
and appends those to your path.
The key here is that on OS X, the Terminal opens a login shell by default, while on Linux, shells are usually started as non-login shells. Josh Staiger has a good explanation of login vs non-login shells.
So, there are essentially only these two three where you can set paths:
-
/etc/profile
(which callspath_helper
) -
/etc/paths
and/etc/paths.d
(called frompath_helper
) - your shell configuration file (
.bash_profile
)
The paths in /etc/paths
and /etc/paths.d/*
are typically added to PATH
by path_helper. path_helper
is run from /etc/profile
, so it is run when bash is invoked as an interactive login shell, but not when bash is invoked as a non-login shell or a non-interactive shell.
/etc/paths
contains /usr/local/bin
at the end by default, and /etc/paths.d/
is empty by default.
Terminal and iTerm 2 open new shells as login shells by default, and the shell opened when you ssh to your computer is also a login shell. Many terminal emulators on other platforms, tmux
, and the shell mode in Emacs open new shells as non-login shells though.
I have added this line to /etc/launchd.conf
:
setenv PATH ~/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/libexec:/usr/texbin
It changes the value of PATH
of the root launchd process. The value is inherited by all other processes, including per-user launchd processes. You can apply changes to /etc/launchd.conf
by restarting, or by running launchctl < /etc/launchd.conf; sudo launchctl < /etc/launchd.conf
and relaunching processes.
On OS X, ~/.profile
is not read when you log in graphically. If both ~/.bash_profile
and ~/.profile
exist, bash does not read ~/.profile
either.
~/.MacOSX/environment.plist
stopped working in 10.8.