11

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 if etc/profile and ~/.profile are the only files setting PATH 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!

16

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.

4

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.

  • I'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. – Larry Lawless Sep 7 '15 at 8:44
  • I 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. – Klaatu von Schlacker Sep 7 '15 at 20:06
  • 1
    I basically want to know the ins and outs of it. I wish Ken Thompson was my father :) – Larry Lawless Sep 8 '15 at 21:58
  • You'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! – Klaatu von Schlacker Sep 8 '15 at 23:32
  • In Linux Mint 18 Cinnamon be sure to check /etc/profile.d/jdk_home.sh I renamed this file to jdk_home.sh.old and now my path does not keep getting overridden and I can call java -version and see Java 9 as expected. Even though I correctly selected Java 9 in update-aternatives --config java this jdk_home.sh file kept overriding the $PATH – flyingdrifter Dec 9 '17 at 20:22
2

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.

0

Stuff, that I dont see:

  • X stuff
  • Masterfiles from where .profile etc are copied over on account creation
  • pam_env
  • A recent thread on Debian, where this is discussed in some detail.

As for Ken Thompson you may be surprised at his: "Views on Linux".

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.