When bash sources your .bashrc

February 8, 2009

Since I just looked up the rules on when bash sources your .bashrc (and did some testing), here's the rules on what gets sourced when, for reasonably current versions of bash. Making this more confusing is that bash apparently uses heuristics for some of its decisions.

  • login shells do not source your .bashrc; they source only your profile (bash looks at various names, but I just use .profile).
  • non-login interactive shells source your .bashrc.
  • shells started by ssh to run remote commands should source your .bashrc, assuming that bash got its heuristics right to recognize that this was happening.

  • otherwise, non-interactive shells (such as those running scripts) do not source .bashrc.

(Non-login interactive shells are common in today's environments, because there are now a lot of things that start new shell sessions without bothering to make them login shells; examples include the various X terminal emulators (xterm et al) and screen. In fact in some environments all of your shells will be non-login interactive shells, and you won't really have a login shell as such.)

Various command line arguments can influence bash's idea of what its environment is, or explicitly suppress bits of this; see --login, --noprofile, and --norc.

Since shell options only affect the current shell, they need to be set in your .bashrc so that they affect non-login interactive shells. Environment variables such as $PATH could theoretically go in your profile and be inherited by subshells, but most people put them in their .bashrc too and just have their profile source their .bashrc. Plus, this is the easiest way to alter your $PATH to make things like 'ssh host private-command' work.

(On some systems this is quite important, because rsync is not on the default $PATH. Solaris 10 is one example of this.)

As far as I can see, bash provides no clear sign about what sort of environment the shell session is running in. If this matters, you are left to deduce things through various signs, none of which are necessarily entirely accurate.

(This issue came up here recently, as we were trying to work out what we needed in .bashrc and why on our Solaris 10 machines. No one could remember exactly what had to be where.)


Comments on this page:

From 93.104.96.82 at 2009-02-08 08:08:10:

I think zsh(1) solved this nicely:

  • first it runs zshenv, which sets up $PATH etc.
  • on a login shell, it runs zprofile
  • on an interactive shell, it runs zshrc, which sets the prompt, defines interactive functions etc.
  • on a login shell, it runs zlogin
  • on logout, it runs zlogout

All files can be in /etc, $HOME, or a custom $ZDOTDIR.

---Christian Neukirchen

By cks at 2009-02-09 18:01:48:

In thinking about this, I think that the difficult thing for any shell is going to be the 'ssh host command' issue. If you have any aspirations of your shell being used to write shell scripts, you do not want to source a startup file for every non-interactive shell, but you do want to source a startup file for the ssh case so that people can set a custom $PATH and so on. So you have to use heuristics to tell the two apart.

(And in at least some cases, doing this in .ssh/environment is not good enough even if that is allowed.)

Written on 08 February 2009.
« An illustration of one reason that documentation is hard
I hate flaky systems, Fedora 10 and/or hardware edition »

Page tools: View Source, View Normal.
Search:
Login: Password:

Last modified: Sun Feb 8 00:10:16 2009
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.