## 3.4. Login Shells, Interactive Shells

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.

### 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.

### 3.4.2. Interactive 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.

--JP and SJC

Copyright © 2003 O'Reilly & Associates. All rights reserved.