2014年(7)
分类: LINUX
2014-02-20 16:07:20
Each Unix shell (sh, csh, etc.) can be in interactive mode or noninteractive mode. A shell also can act as a login shell or a nonlogin shell. A shell is a shell is a shell — e.g., a login bash shell is the same program (like /bin/bash) as a nonlogin bash shell. The difference is in the way that the shell acts: which setup files it reads, whether it sets a shell prompt, and so on.
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.
In general, shells are used for two jobs. Sometimes, a shell handles commands that you type at a prompt. These are interactive shells. Other times, a shell reads commands from a file — a shell script (Section 35.2). In this case, the shell doesn't need to print a prompt, to handle command-line editing, and so on. These shells can be noninteractive shells. (There's no rule that only noninteractive shells can read shell scripts or that only interactive shells can read commands from a terminal. But this is generally true.)
One other difference between interactive and noninteractive
shells is that interactive shells tie STDOUT and STDERR to the current terminal,
unless otherwise specified.
It's usually easy to see whether a particular invocation of
your shell is interactive. In C shells, the prompt variable will be set. In the Korn shell and bash, the -i flag is set. Your current flags may be displayed
using the $- variable:
prompt$ echo $-
imH
The previous example, from an interactive bash shell, shows that the flags for an interactive shell (i), monitor mode (m), and history substitution (H) have been set.