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.

Login/Non-Login Shell

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

Possible answers I’ve seen:

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 the first process that executes under your user ID when you log in for an interactive session. (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 first character of argument zero, 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.

Another way to start a login shell is to invoke it with a --login option:

bash --login

Another way to start a login shell is to set the first character of argument zero to a - when invoke the shell:

exec -a -bash bash

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* ]]

Login and/or Interactive

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:

  • non-login, non-interactive:

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

  • non-login, interactive:

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

  • login, non-interactive:

    This use case is very rare. One way to start this kind of shell is:

    echo 'shopt login_shell; echo $-' | ssh {server}
    
  • login, interactive:

    When you login from terminal after entering username and password, the started shell is a login, 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

Basic sourcing rules are:

  • When Bash is invoked as a login shell, it sources /etc/profile then the first one in [ ~/.bash_profile, ~/.bash_login, ~/.profile ].

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

  • When Bash has its standard input connected to a network connection (as when executed by a remote shell daemon such as sshd), it sources ~/.bashrc.

Note that these rules come from real tests, whose results do not exactly match Bash Manual. Specifically, Bash Manual does not mention the case where a login shell is one whose first character of argument zero is a -. Under our tests, this case makes no difference than other login cases.

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 (or whose first character of argument zero is a -).

  • Bash shells with network-connected stdin source rc.