Notes on shell initialization
Different shells read different files when starting up. I'm collecting
here the behavior of the shells I'm exposed to. I'm not interested here
in the system files (like /etc/profile) which could be read
as I don't have any control over them.
Kinds of shells
Shells can be invoked in different circumstances. To serve as interactive comman interpreters, to execute scripts, to execute commands passed as argument. Two aspects are considered for the reading of initialization files: is the shell a login shell? and is the shell interactive?
Login shells
Login shells are usually those whose first argument (the one which
contains the program name) starts wioth a - or which are
passed a -l option. The former is done automatically when
doing a console or network login. Terminal emulator can usually be
configured to launch a login shell or not (for
instance xterm launches a login shell if passed
an -ls option).
Login with a X display manager usually do not go through a login shell
but the display managers have their own set up files. Sometimes they try
to emulate the reading of the shell login file, with more or less
success. Two examples, on the Ubuntu version I'm currently using and
with the display manager I'm currently using, the set up is
reading $HOME/.profile and does not try anything else
whatever you shell is. On Solaris years ago, the setup was able to
read $HOME/.login if your shell was csh. Some
window managers do not try to read the shell login setup file and are
only using only their own user setup files such
as $HOME/.xsession, $HOME/.xinitrc
or $HOME/.xprofile. The complexity is even worse as this
process is usually heavily customizable and distribution integrators do
take advantage of that, so the help that you can find on the web may not
apply to your version of your distribution.
When a shell is a login shell, the common practice is to define the
environment variables which will be inherited by all programs launched
directly or indirectly by the shell. Some other things which can be set
there is umask, the settings of terminal
(with stty). Before display manager and their graphical
login, it was also common to launch the X environment.
Interactive shells
Interactive shells are usually those which are reading the commands from standard input with standard input connected to a terminal. Shells usually have slightly different behavior for interactive shells such as printing a prompt before each command and not exiting in presence of errors. There may be options which change that behavior.
The common practice for the interactive shell initialization file is to define things which are useful only in these situations such as the prompt, functions and aliases for common commands, configurating the auto-completion of the shell if there is one.
Some also like to define the environment variables in the same way as for a login shell. Depending on what is defined, that can interfere with some shell usages.
Shells behavior
Posix shell
Posix doesn't specify anything to be read for login shell.
The ENV environment variable is used, after parameter
expansion, to specify a file which is read when and only when an
interactive shell is invoked.
dash
.profile is read for login shells.
$ENV is read for interactive shells, included login
one. ENV can be set in .profile.
NetBSD sh
.profile is read for login shells.
$ENV is read for all shells, interactive or not, included
login one. ENV can be set
in .profile. Reading of $ENV may be avoided by
setting the posix option.
bash
the first of .bash_profile, .bash_login,
or .profile is read for login shells.
.bashrc is read for interactive non-login shell.
$BASH_ENV is read for non-interactive shells.
When invoked as sh, bash only looks
at .profile for login shell, and at $ENV for
interactive one.
ksh
.profile is read for login shells.
$ENV, or .kshrc if it does not exist, is read
for interactive shells.
zsh
.zshenv is read for all shells.
.zprofile is read for login shells.
.zshrc is read for interactive shells.
.zlogin is read for login shells.
When invoked as sh or ksh, zsh
reads .profile for login shells, and $ENV for
interactive one.
mksh
.profile is read for login shells.
$ENV, or .mkshrc if it does not exist, is read
for interactive shells
csh
.cshrc is read for all shells. prompt is set
only for interactive shells. Some systems have a which
commands which read .cshrc with prompt set to
an empty string.
.login is read for login shells.
tcsh
.tcshrc, or .cshrc if it does not exist, is
read for all shells. prompt is set only for interactive
shells. Some systems have a which commands which
read .cshrc with prompt set to an empty
string.
.login is read for login shells.