Bash has a pretty complicated logic on which scripts it runs and when.
But it mostly boils down to:
- if you have settings that are inherited from parent process to child (environment variables,
ulimits), you usually need to set them only once at each login, so it would be more efficient to put them into
.profile rather than
- if you have settings that are both inherited and additive (e.g. adding something to the existing value of
PATH with a construct like
PATH=$PATH:/some/directory), then putting such a setting in
.bashrc would cause that addition happening a second time whenever you start another shell process, which would be silly and wasteful.
For example, if you set
.bashrc, it works just fine in your main shell. But when you start an editor and then use its shell escape functionality, you may find that your PATH now has a value like
...:/some/directory:/some/directory. Each layer of child shells would add the directory to the PATH another time. Inheritable, additive settings are generally best placed in
- if you have settings that are not inherited between regular processes, like shell aliases or functions, you'll want to define them in
.bashrc. If you defined them in
.profile, you could find them not available in shells started using the shell escape functionality in various applications. (This also means you'll probably want to add a command to source your
.bashrc at the end of your
.profile so that the session's primary login shell will also get those definitions, unless your distribution's standard
/etc/profile or default
.profile already provides that functionality.)
With the graphical user interface, there is one more complication. The GUI session will usually source the contents of
.profile or equivalent at login (because the respective session start-up script is run as a login shell), so any inheritable settings made there will usually be inherited by the desktop environment, and in turn, any application that is started using desktop icons or menus.
Any terminal windows within a X11 GUI session can be set up in one of two ways:
- completely independent terminal sessions: each terminal window is treated as an independent login session, and the environment is built up from some basic system-wide defaults for the shell within the terminal emulator process. In this case, each new terminal window will run as a login shell, and so will execute
.profile or equivalent when opened.
- each terminal window is treated as a part of the main GUI login session: in this case, the shells inside terminal windows are started as non-login shells, and will only execute
.bashrc or equivalent. The inheritable settings are inherited from the main GUI login session, via desktop environment/window manager processes.