Complete view of where the PATH variable is set in bash
Solution 1
There are many places where PATH
can be set.
The login
program sets it to a default value. How this default value is configured is system-dependent. On most non-embedded Linux systems, it's taken from /etc/login.defs
, with different values for root and for other users. Consult the login(1)
manual on your system to find out what it does.
On systems using PAM, specifically the pam_env
module, environment variables can be set in the system-wide file /etc/environment
and the per-user file ~/.pam_environment
.
Then most ways to log in (but not cron jobs) execute a login shell which reads system-wide and per-user configuration files. These files can modify the value of PATH
, typically to add entries but sometimes in other ways. Which files are read depend on what the login shell is. Bourne/POSIX-style shells read /etc/profile
and ~/.profile
. Bash reads /etc/profile
, but for the per-user file it only reads the first existing file among ~/.bash_profile
, ~/.bash_login
and ~/.profile
. Zsh reads /etc/zshenv
, ~/.zshenv
, /etc/zprofile
, ~/.zprofile
, /etc/zlogin
and ~/.zlogin
. Many GUI sessions arrange to load /etc/profile
and ~/.profile
, but this depends on the display manager, on the desktop environment or other session startup script, and how each distribution has set these up.
Solution 2
The initial PATH variable is usually set in /etc/profile
Sometimes a sys admin will also put PATH variables to source in /etc/profile.d
These are the system PATH vars that everyone who logs in inherits by default (unless over-ridden locally). This usually sets obvious paths, like /usr/bin
, although at my job we use /opt
and a few custom locations extensively, so those are set there as well.
On a per-user login basis accounts, PATH may also be defined in ~/.profile
. That might define things that not all users have access to; maybe department heads can run binaries from /opt
but other users aren't bothered with those binaries. Users can modify that file themselves, too, and the nice thing about .profile
is that it is not shell-specific; if you login, the PATH set there gets sourced.
For shell-specific logins, PATH may be defined in ~/.bash_profile
, ~/.bashrc
, or .cshrc
, or similar. Users can set PATH here if they want specific paths for specific shells, or if they just happen to maintain all their personal preferences there.
In summary: /etc/profile and /etc/profile.d are traditionally cascading settings; they get inherited and usually are added to in personal dot-files (although a user could choose to override them instead). Personal dot-files are usually set by a user.
Of course, a shell has environment variables, too, so a local environment variable can also add or override default PATH in any of the configuration files.
Solution 3
To add to the other answers:
bash
will set PATH
to a hard-coded default value if it's not set in the environment. On an Ubuntu Server 16.04.2 machine, I get:
$ env -i bash -c 'echo $PATH'
/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:.
We can check that this value is indeed hard-coded, and not read from the environment or some file, using the strings
utility:
$ strings /bin/bash | grep /usr/sbin
/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:.
However, I get a different result on my Arch Linux machine:
$ env -i bash -c 'echo $PATH'
/usr/local/sbin:/usr/local/bin:/usr/bin
So, it looks like this default is chosen at the time the bash
binary was built, which depends on the OS / distribution in use.
Related videos on Youtube
Larry Lawless
Updated on September 18, 2022Comments
-
Larry Lawless over 1 year
I've read in a couple of places that the
PATH
is set in/etc/profile
or the.profile
file that's in the home dir.Are these the only places that the path is set in? I want a better understanding of it.
In the
/etc/profile
file, as the following comment says"system-wide .profile file for the Bourne shell"
. Does that mean that profile files are the main configuration files for bash?In that file I don't see the
PATH
var being set at all. In the.profile
file in the home directory there's this line:PATH="$HOME/bin:$PATH"
That's resetting
PATH
by the looks because it's concatenating the already set$PATH
string with$HOME/bin:
right? But ifetc/profile
and~/.profile
are the only files settingPATH
where is$PATH
coming from in that line of code if it's not defined in/etc/profile
?Can someone experienced please give a broad and detailed explanation of the
PATH
variable? Thanks! -
Larry Lawless over 8 yearsI've just checked all of those files which you mentioned, ~/.bash_profile and .cshrc do not exist however. The 3 script files in the /etc/profile.d dir: appmenu-qt5.sh, bash_completion.sh & vte.sh do not set the PATH variable either. What do you mean with "a shell has environment variables too" is the default PATH set in the binary /bin/bash program? When I terminal echo $PATH I get: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games but I don't have an idea where that all is being set really.
-
Klaatu von Schlacker over 8 yearsI think I somewhat misread your question, I thought you were asking for all the locations PATH could be set, but I think you are more interested in where PATH is initially set. For that, look at
/etc/bashrc
. This determines how BASH is launched, which should include all initial environment variables. On my system,/etc/bashrc
reads from/etc/profile.d
but it sounds like you only have 3 files in/etc/profile.d
so your distro may be doing it differently. -
Larry Lawless over 8 yearsI basically want to know the ins and outs of it. I wish Ken Thompson was my father :)
-
Klaatu von Schlacker over 8 yearsYou'll get there. Believe me, after you use this stuff on a daily basis for a while, it all starts to sink in, and as long as you keep asking "why?" and reading docs for the answers, you do eventually learn a lot!