3.4.1. Login Shells
When you first log in to a Unix system
from a terminal, the system normally starts
a login shell. (Section 3.4) A login shell is typcally the top-level shell
in the "tree" of processes that
starts with the init (Section 24.2) process. Many characteristics of processes
are passed from parent to child process down this
"tree" -- especially environment variables (Section 35.3), such as the search
path (Section 35.6). The changes you make
in a login shell will affect all the other processes that the
top-level shell starts -- including any subshells (Section 24.4).
So, a login shell is where you do general setup
that's done only the first time you log
in -- initialize your terminal, set environment variables, and so
on. A shell "knows"
(Section 3.19) when it's a login
shell -- and, if it is, the shell reads special setup files (Section 3.3) for
login shells. For instance, login C shells read your
.login file, and Bourne-type login shells read
.profile. Bash may also read
/etc/profile, and
~/.bash_profile or
~/.bash_login or
~/.profile, depending on whether those files
exist and whether the -noprofile option has been
passed (which would disable reading of any startup files).
Nonlogin shells are either subshells
(started from the login shell), shells started
by your window system (Section 24.20), or
"disconnected" shells started by
at (Section 25.5),
rsh (Section 1.21),
etc. These shells don't read
.login or .profile.
In addition, bash
allows a nonlogin shell to read ~/.bashrc or
not, depending on whether the -norc or
-rcfile options have been passed as arguments during
invocation. The former simply disables reading of the file, and the
latter allows a substitute file to be specified as an argument.
Some shells make it easy to know if a particular invocation is a
login shell. For instance,
tcsh sets the variable
loginsh. Check your shell's
manual page for details. Section 4.12 shows
another solution: the
SHLVL variable that's set
in most modern shells. Or you can add the following line to the
beginning of a setup file
that's only read by login shells (Section 3.3). The line sets a shell
variable (Section 35.9) named
loginshell:
set loginsh=yes ...csh
loginshell=yes ...bash and other sh-type shells
Now wherever you need to know the type of shell, use tests like:
if Section 35.13
if ($?loginsh) ...csh-type shells
if [ -n "$loginshell" ] ...sh-type shells (including bash)
This works because the flag variable will only be defined if a shell
has read a setup file for login shells. Note that none of the
variable declarations use the
"export" keyword -- this is so
that the variable is not passed on to subsequent shells, thereby
ruining its purpose as a flag specific to login shells.