63

I'm trying to differentiate these four terms login, non-login, interactive and non-interactive:

  • interactive - login shell
  • interactive - non-login shell
  • non-interactive - login shell
  • non-interactive - non-login shell

As I understand
interactive - non login shell: Start the system, log in to system and open terminal and
non-interactive - login shell: telnet to system and log in

But what about an interactive - login shell?
Does it log in to the system, open virtual terminal and log in? and
non-interactive - non-login shell, is it running automated script in crontab?

2

5 Answers 5

98

The only real misconception you seem to have is about what constitutes a non-interactive, login shell.

Briefly (see here for more details), with examples:

  • interactive login shell: You log into a remote computer via, for example ssh. Alternatively, you drop to a tty on your local machine (Ctrl+Alt+F1) and log in there.

  • interactive non-login shell: Open a new terminal.

  • non-interactive non-login shell: Run a script. All scripts run in their own subshell and this shell is not interactive. It only opens to execute the script and closes immediately once the script is finished.

  • non-interactive login shell: This is extremely rare, and you're unlikey to encounter it. One way of launching one is echo command | ssh server. When ssh is launched without a command (so ssh instead of ssh command which will run command on the remote shell) it starts a login shell. If the stdin of the ssh is not a tty, it starts a non-interactive shell. This is why echo command | ssh server will launch a non-interactive login shell. You can also start one with bash -l -c command.

If you want to play around with this, you can test for the various types of shell as follows:

  • Is this shell interactive?

    Check the contents of the $- variable. For interactive shells, it will include i:

    ## Normal shell, just running a command in a terminal: interacive
    $ echo $-
    himBHs
    ## Non interactive shell
    $ bash -c 'echo $-'
    hBc
    
  • Is this a login shell?

    There is no portable way of checking this but, for bash, you can check if the login_shell option is set:

    ## Normal shell, just running a command in a terminal: interacive
    $ shopt login_shell 
    login_shell     off
    ## Login shell; 
    $ ssh localhost
    $ shopt login_shell 
    login_shell     on
    

Putting all this together, here's one of each possible type of shell:

## Interactive, non-login shell. Regular terminal
$ echo $-; shopt login_shell
himBHs
login_shell     off

## Interactive login shell
$ bash -l
$ echo $-; shopt login_shell
himBHs
login_shell     on

## Non-interactive, non-login shell
$ bash -c 'echo $-; shopt login_shell'
hBc
login_shell     off

## Non-interactive login shell
$ echo 'echo $-; shopt login_shell' | ssh localhost
Pseudo-terminal will not be allocated because stdin is not a terminal.
hBs
login_shell     on
14
  • I want to clear that 1) For me login to gui means start the system, login to system and open terminal 2) doing telnet or ssh is interactive login shell means example i had given for non-interactive login shellis wrong.
    – d a i s y
    Feb 4, 2017 at 3:53
  • @daisy thanks for the clarification; answer edited.
    – terdon
    Feb 4, 2017 at 7:59
  • okay and gui is irrelevant, interactive non-login shell: just open a new terminal either locally or remotely via telnet or ssh
    – d a i s y
    Feb 4, 2017 at 8:56
  • @daisy yep, sounds about right. But please read Muru's answer carefully as well since that explains that, essentially, this is a matter of semantics and only affects what startup files are read by the shell. Also see here for an even more comprehensive overview of the different shell types.
    – terdon
    Feb 4, 2017 at 13:10
  • 1
    Non-interactive login shells are not that uncommon, for example git uses them, IIRC.
    – quazgar
    Mar 6, 2018 at 8:40
10

Essentially, whether a shell is login or not, interactive or not matters for exactly one reason:

The initialisation files and default options set depend on whether a shell is login or not and interactive or not.

Correspondingly, whether a shell is login or not or interactive or not depends solely on the invocation used - the exact command name and options.

The two properties are otherwise orthogonal - whether a shell is login or not has no bearing on determining whether it's interactive or not.

Bash starts a login shell if any of these are true:

  • argv[0], the name of the command it was invoked as, starts with a -
  • the -l option is specified

Similar, bash starts an interactive shell if any of these are true:

  • it was not specified a file to execute (i.e., the command wasn't bash some/file) or a command string to run (bash -c 'foo') (the actual condition is a bit more complex, see the manual)
  • the -i option was specified

Notably (and paradoxically), the latter implies that bash -ic 'foo' starts an interactive shell.

So the following starts a login, interactive shell, even though it has nothing whatsoever interactive about it and the invocation had nothing to do with logging in:

bash -lic true

That logging in via console or GUI starts a login shell (or maybe not) is entirely an effect of the login process using the appropriate invocation.

The conditions and effects are described in detail in the bash manual, section on Startup Files.


A major source of confusion is that there is another common meaning for "login" shell:

A user's login shell is the shell defined in that user's passwd entry (which may come from /etc/passwd, LDAP or some other source).

The login program, SSH, etc. start this shell as a login shell in the sense meant in the rest of the answer - with a leading - in the command name, usually. If you wanted to be particularly confusing, you could say:

Some login processes start the login shell of the user as a login shell.

Note that GUI login starts a login shell purely because the developers thought it convenient - LightDM runs a script on login which obviously isn't interactive and certainly doesn't depend on the user's login shell (in the second sense). Do not depend on the display manager starting a login shell, though - not all of them do, and on Wayland and GNOME, the login process doesn't use shell scripts at all.

4

Login shell:

The first process that executes under our user ID when we log in to a session. The login process tells the shell to behave as a login shell with a convention: passing argument 0, which is normally the name of the shell executable, with a “ - ” character prepended

Interactive shell:

Reads commands from user input on a tty. Among other things, such a shell reads startup files on activation, displays a prompt, and enables job control by default. The user can interact with the shell. A shell running a script is always a non-interactive shell.

Simply put: Interactive shell require user input, while non-interactive shell are run by scripts and don't require user inputs.

9
  • So the examples that are given correct.
    – d a i s y
    Feb 3, 2017 at 10:39
  • Yes daisy your in the right place. Feb 3, 2017 at 10:44
  • 1
    @daisy no! The GUI has absolutely nothing to do with it. This is about command line shells, not graphical shells (which also exist but are a different beast).
    – terdon
    Feb 3, 2017 at 11:13
  • 1
    @George no, there are two mistakes: logging in via the GUI does not start a login shell (or any other kind of relevant shell) and logging in to a remote system via telnet starts a telnet shell, but via ssh starts an interactive login shell.
    – terdon
    Feb 3, 2017 at 11:48
  • 1
    @George actually, I stand corrected. Some GUI login managers might start a login shell to read .profile (I thought they just source .profile manually, but I might be wrong).
    – terdon
    Feb 3, 2017 at 11:58
2

One category of shell (Non-interactive, login shell with hBc options) is missing in the accepted answer. It is commonly used unlike the one with hBs options to execute a command in a ssh session. To see, compare 4 and 5. I included it with others.

# Combination of login and interactive shells

#1. Interactive, login shell: himBHs
{
 bash --login
 echo $-
 shopt login_shell 
 logout    # use CTRL-D   : Note the difference here between 1 and 2
}                                                       
#2. Interactive, no-login shell: regular terminal: himBHs
{
 bash   
 echo $-
 shopt login_shell
 exit     # use CTRL-D   : Note the difference here between 1 and 2
}
#3. Interactive, no-login shell: executing commands from standard input - scripts: himBHs
{
cat <<-EOF > myfile && bash -s < myfile         
echo $-
shopt login_shell
EOF
}
#4. Non-interactive, login shell  - takes commands from standard input - pipes: hBs
echo 'echo $-; shopt login_shell' | ssh localhost   
#5. Non-interactive, login shell  - executes commands : hBc
ssh localhost  'echo $-; shopt login_shell'         
#6. Non-interactive, no-login shell : hBc
bash -c 'echo $-; shopt login_shell'                

What is a login Shell?

It reads and executes commands from the first available file (if exists) during login session in the following order:

  1. /etc/profile
  2. ~/.bash_profile,
  3. ~/.bash_login, and
  4. ~/.profile

It reads and executes commands from all files (if exists) during logout in the following order:

  1. ~/.bash_logout and
  2. /etc/bash.bash_logout

Note: The difference in calling login files (only the first available file) and logout files (all files).

    echo 'echo "Logging out ... $(date)"' >> ~/.bash_logout
    echo 'echo "Logging out from /etc/bash.bash_logout... $(date)"' | sudo tee -a /etc/bash.bash_logout 
    bash --login
    Ctrl-D    # logs out

Note: A confusion always comes up when ~/.bashrc file commands are executed during login shell session. Generally, commands in ~/.bashrc file should not be executed during login shell. However, if it occurs, it is because of ~/.bash_profile file includes ~/.bashrc file in it. Verify your ~/.bash_profile file. This is a common behavior in Fedora based linux distributions.

What is a no-login shell?

It reads and executes commands from user-specific settings file: ~/.bashrc

What is a non-interactive session?

It reads and executes commands from BASH_ENV variable. It is also a way to control the behavior of non-interactive session.

echo "HELLO=WORLD" > ~/myrc
BASH_ENV=~/myrc bash -c 'echo $BASH_ENV; echo $HELLO'

Note: BASH_ENV must contain full-path of shell-script file.

Note: ssh remote non-interactive shell session does not read BASH_ENV. Instead, it reads ~/.bashrc file of remote user in remote system.

Note: ssh remote sessions do not execute commands from files mentioned in login shell (~/.bash_profile).

This will not work:

BASH_ENV=~/myrc ssh localhost 'echo $BASH_ENV; echo $HELLO'

ssh remoteuser@localhost  'echo $HELLO'

This will work: Because, .bashrc belongs to current user who is assumed as remote user, and remote system is assumed as localhost in this example.

echo 'HELLO=WORLD' >> ~/.bashrc
ssh localhost  'echo $HELLO'

How to control the behavior of login shell?

  1. using --noprofile option to disable reading commands from files mentioned above in login shell.

    echo "HELLO=WORLD1" >> ~/.bash_profile
    bash --login
    echo $HELLO
    bash --login --noprofile
    echo $HELLO
    

How to control the behavior of no-login shell?

  1. using --rcfile option to specify user-specific rc file
  2. using --norc option to disable reading commands from files mentioned above in no-login shell
1
  • 1
    Only the first available of ~/.bash_profile, ~/.bash_login and ~/.profile is read (see the Bash Reference Manual 6.2)
    – muru
    Jan 5, 2021 at 4:03
0

I'd like to mention, that you can start an interactive login shell by:

  1. executing sudo /bin/login and typing in your credentials
  2. executing exec -l /bin/bash
  3. executing su -
  4. and like answers above stated, using ssh and login in to a remote machine

Also, you can check (in bash) if it the shell is login by typing echo $0 and if the output starts with a dash -, then it is a login shell.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .