Interactive and login shells in Bash

Interactive and login shells in Bash

You might ever get confused because some bash config scripts are not executed, but they are sometimes executed multiple times.

This post will reveal the reason for these phenomenons.

The basic definitions

When being invoked with none of these options: --noprofile, --norc, --rcfile, --init-file, a bash session defines the startup scripts to be loaded and their orders based on two boolean properties: interactivity (interactive/non-interactive) and login type (login/non-login).

Interactive shell is a shell whose input, error, output are connected to terminals (tty).
Typically, an interactive shell reads from/writes to a terminal. The -i option is used to set interactive mode explicitly. On the other hand, [[ -z "$PS1" ]] is a handy condition to check if a shell is in interactive mode. Likewise, this can be checked via whether $- includes i character, i.e., [[ $- == *i* ]].

Login shell: when being invoked with the --login (or -l) option, the shell becomes a login shell.

Startup scripts and their execution orders

If a shell is a login shell and the option --noprofile is not used when the shell is invoked, the startup scripts' execution orders become: /etc/profile, ~/.bash_profile, ~/.bash_login, ~/.profile. The files that do not exist are ignored without throwing any error.
In addition, when a login shell exits, it executes ~/.bash_logout (if exists).

If a shell is invoked in interactive mode (invoked by a terminal or invoked with the -i option), and the --norc option is not used, ~/.bashrc is read and executed if the script exists. This script can be specified with the --rcfile option.

If a shell is invoked in non-interactive mode (running a command), the BASH_ENV environment variable is expanded. If there is a value that matches an existing readable file, that file is executed.

When a graphical session (gnome, unity, kdm, kdm, ..) starts, their behaviors highly depend on the graphical programs, which are mostly configurable. There is no consistent rule for all graphical programs. Nonetheless, with the same program, they vary from version to version. Typically, ~/.profile is read, but you should not rely on this behavior.

Some Linux distributions have a default ~/.profile which sources ~/.bashrc, which explains why ~/.bashrc gets run twice. Besides, you should also check /etc/bashrc, /etc/bash.bashrc, /etc/profile. It is worth noting that it is common in many distributions that all scripts in /etc/profile.d/ directory are loaded.