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 the 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. 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 issue is aggravated 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.

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.