The Shell acts as the interface between the Linux kernel and the user, serving as the primary mechanism for system management and communication. Depending on the initialization method, a Shell session operates in one of four distinct modes, defined by two criteria: authentication status (Login or Non-login) and interactivity (Interactive or Non-interactive).
There are four possible combinations of these modes:
- Interactive Login Shell
- Interactive Non-login Shell
- Non-interactive Login Shell
- Non-interactive Non-login Shell
Identifying Interactive Shells
Determining whether a Shell is interactive can be achieved through two primary methods.
1. Checking the $- variable
The $- variable displays the current flags set for the Shell. If the output contains the letter i, the session is interactive.
Example 1: Checking a standard desktop terminal (Interactive)
user@linux-box:~$ echo $-
himBH
The presence of i confirms an interactive session.
Example 2: Checking inside a script (Non-interactive)
user@linux-box:~$ cat session_info.sh
#!/bin/bash
echo "Current flags: $-"
user@linux-box:~$ bash ./session_info.sh
Current flags: hB
The absence of i indicates a non-interactive session. Note that the script must run in a new process to demonstrate this behavior.
2. Checking the $PS1 variable
The $PS1 variable defines the primary prompt string. If its set and non-empty, the Shell is interactive; non-interactive sessions typically unset this variable.
Example 1: Checking $PS1 in a terminal
user@linux-box:~$ echo $PS1
\u@\h \W\$
The value is set, confirming an interactive session.
Example 2: Checking $PS1 in a script
user@linux-box:~$ cat session_info.sh
#!/bin/bash
echo "Prompt variable: $PS1"
user@linux-box:~$ bash ./session_info.sh
Prompt variable:
The empty output indicates a non-interactive session.
Identifying Login Shells
To determine if the current Shell is a login shell, you can use the shopt command with the login_shell option. The shopt command controls various Shell behavioral options.
Example 1: Checking in a GUI terminal emulator
user@linux-box:~$ shopt login_shell
login_shell off
Example 2: Checking in a virtual console (TTY) after login
user@linux-box:~$ shopt login_shell
login_shell on
Example 3: Checking within a script
user@linux-box:~$ cat session_info.sh
#!/bin/bash
shopt login_shell
user@linux-box:~$ bash ./session_info.sh
login_shell off
Simultaneous Verification
You can verify both properties at once by combining the commands. For instance:
echo "PS1: $PS1"; shopt login_shell
Alternatively:
echo "Flags: $-"; shopt login_shell
Common Shell Startup Scenarios
1. Console or SSH Login
Accessing the system via a physical console (TTY) or a standard SSH connection results in an interactive login shell.
user@linux-box:~$ echo $PS1; shopt login_shell
\u@\h \W\$
login_shell on
2. Explicit Login Invocation
Running the bash command without arguments typically spawns a non-login shell. Adding the --login (or -l) flag forces it to act as a login shell.
user@linux-box:~$ cat session_info.sh
#!/bin/bash
echo "Flags: $-"; shopt login_shell
user@linux-box:~$ bash -l ./session_info.sh
Flags: hB
login_shell on
3. Subshells via Grouping
When creating a subshell using parentheses () or command substitution, the child process inherits the interactive and login attributes of the parent. Because these are fork operations without a subsequent exec, configuration files are not reloaded.
user@linux-box:~$ bash
user@linux-box:~$ (echo $PS1; shopt login_shell)
\u@\h \W\$
login_shell off
user@linux-box:~$ bash -l
user@linux-box:~$ (echo $PS1; shopt login_shell)
\u@\h \W\$
login_shell on
4. Remote Command Execution via SSH
Executing a command directly on a remote host via SSH (without logging in) creates a non-interactive, non-login shell.
user@linux-box:~$ ssh localhost 'echo $PS1; shopt login_shell'
login_shell off
5. Desktop Environment Terminal Emulators
Opening a terminal window within a graphical desktop environment (like GNOME or KDE) typically launches an interactive, non-login shell.