I have a basic understanding on how the $PATH can be set, but is there a documentation that fully describes where Mac OS gets all the paths that get appended to $PATH? I'm aware of things like /etc/profile
, /etc/paths
, and /etc/profile.d
, but are there other scripts that eventually affect the value of $PATH? I'm also not very familiar between the non-login, and login shells (.bashrc
, .bash_profile
), but I'm aware of the basic differences.
2 Answers
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
)
-
Thanks for the concise, and informative answer. So I guess I kind of understand, which scripts/artifacts influence the $PATH then. So does this mean the
/etc/profile
is a script mainly used by bash? I don't have experiences with other shells, but I assume they follow a different structure? Oct 3, 2013 at 15:38 -
The
/etc/profile
is used by most (all? Not 100% sure) shells. That's why it's a good choice to put things in that you want everywhere, like PATHs. Bash reads.bash_
files while Zsh for example reads.zshrc
in addition to others. It depends on the shell.– slhckOct 3, 2013 at 15:46 -
"In OS X, additionally, there is path_helper which reads the contents of /etc/paths.d and appends those to your path." No,
path_helper
is not called for interactive non-login shells (nor non-interactive shells). It is called for interactive login shells, by/etc/profile
actually. Sep 15, 2019 at 15:34
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.