Historically, Bash invocation has confused many users, both experts and newbies. Bash forums are filled with questions such as:

• Why weren’t my commands executed?

• Which file to source at Bash startup?

• What’s the difference between .bashrc, .bash_profile, .profile, .bash_login

So we are going to clarify how Bash is invoked in this text.

The first question people ask is often: What is a login shell?

A login shell is one whose first character of argument zero is a -, or one started with the --login option. (Origin)

…a login shell is one that is spawned by the login process. (Origin)

Putting them together, a login shell is used for user login, and is identified by, either a - as argument 0, or a --login option.

The login shell of a user is stored in /etc/passwd. And you can use getent passwd <username> to see it. The login process will spawn the login shell on a successful login.

It’s also possible to manually start a login shell by invoking it with a --login option. You can also link it to - and invoke it, and this is also a login shell even without the --login option.

To check whether a shell is a login shell, use:

shopt -q login_shell


## Interactive/Non-Interactive Shell

The definition in Bash Manual is:

An interactive shell is one started without non-option arguments, unless -s is specified, without specifying the -c option, and whose input and error output are both connected to terminals (as determined by isatty(3)), or one started with the -i option.

The statement is more clearly viewed as:

• (

• (without non-option arguments, unless -s is specified)

• and

• (without specifying the -c option)

• and

• (whose input and error output are both connected to terminals (as determined by isatty(3)))

• )

• or

• (

• one started with the -i option.
• )

To check whether a shell is an interactive shell, use:

[[ \$- != *i* ]]


Now that login-ness and interactive-ness classify Bash shells in different dimensions, users may wonder whether a shell can be either or both.

The answer is, a shell can be none, either or both, because these two properties are orthogonal. Here are some typical use cases exemplifying these different properties:

When you run a shell script in a terminal window with bash myscript.sh, the started shell is a non-login, non-interactive shell.

When you start another shell without any arguments with bash, the started shell is a non-login, interactive shell.

This use case is very rare because if a login program is non-interactive, then usually we don’t call it a shell…

So the example here is artifical: bash -l myscript.sh starts a login, non-interactive shell.

## Startup Scripts

Bash sources different scripts on start, depending on how it is invoked. Here’s a standard list of them:

~/.bash_login
~/.bash_profile
~/.bashrc
~/.profile
/etc/profile


There are several sourcing rules, of which the most basic ones are as follows:

• If Bash is invoked as an interactive login shell, or as a non-interactive shell with --login option, it sources /etc/profile and the first one in [~/.bash_profile, ~/.bash_login, ~/.profile].

• If Bash is invoked as a non-login, interactive shell, it sources ~/.bashrc.

The idea is that, Bash sources startup scripts only when being used interactively (or forced with --login). Depending on login/non-login property, either a profile or a rc file is sourced.

However, please note that stating login shells alway source profile is wrong. A counter example is, when executing a script with argument 0 -, the shell is a login shell, but no profile will be sourced. The shell must be interactive for the statement to hold.

An additional case is when Bash has its standard input connected to a network connection, as when executed by a remote shell daemon (for example, sshd). If so then Bash sources ~/.bashrc.

## Conclusion

To summarize:

• Interactive shells source either profile or rc depending on whether it’s login/non-login.

• Non-interactive shells source profile when invoked with --login.

• Bash shells with network-connected stdin source rc.