Why .profile (and not .bashrc) appends ~/bin to path?

Since .bashrc is more "generic" (in the sense that .profile sources it), why "include ~/bin to path" procedure is not inside .bashrc? Why the user would not want it in a non-login shell? (Especially nowadays, where non-login shells are more common*.)

I know I can manually do such change, but I want to know if there is a reason.

*can't prove it, but I think that is the case.


~/.bashrc and /etc/bash.bashrc are run every time an interactive bash shell is started.

In contrast, ~/.profile and /etc/profile are run every time any login shell is started. So it does not have to be a bash shell, but it does have to be a login shell (and many bash shell instances are not login shells).

  • A bash shell is a shell where the shell program that provides it is bash, rather than some other program, such as dash.
  • A login shell is a shell that is started automatically as a consequence of logging in, to provide the user interface (graphical or command-line) for the login. When a login shell is exited, the login terminates.

Therefore, putting a commend that appends entries to PATH in a bashrc file would:

  1. Do nothing when the shell is not bash, which is often the case. For example, PATH would be unmodified when you're in a graphical login session. Remember, PATH is not just used by command-line programs.

  2. Append it over and over again in the presence of nested bash shells. So, if you start a shell within a shell--which is very common, for a variety of reasons--then you'll have multiple ~/bin entries stacked onto your PATH. This makes the PATH environment variable difficult to read, and sometimes also decreases performance.

These would be undesirable. Thus it would be wrong to put this in a bashrc file; it really belongs in ~/.profile. ~/.profile is the right place for:

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi

Non-login shells have login shells (or something that behaves like a login shell) as their parent, and inherit most of their environment variables, including PATH, from this login shell. So putting path-modifying commands in ~/.profile requires that you log out and back in for them to be effective, but it affects the environment of non-login shells too (as well as the environment for programs that are not shells, since every program gets its own set of environment variables--called its "environment"--inherited from its parent process).


It's because traditionally environment variables go only in /etc/profile or .profile. The bashrc file is for things like aliases, prompt settings, shell options and so forth (i.e. things that relate directly to the shell).