I understand the basic difference between an interactive shell and a non-interactive shell. But what exactly differentiates a login shell from a non-login shell?

Can you give examples for uses of a non-login interactive shell?

  • 35
    I think the question is better phrased as "Why do/should we care to differentiate login and non-login shells?" Many places on the web already tell us what are the differences, in terms of what startup files each read; but none of them seems to answer the "why" in a satisfactory and convincing way. Example use cases where you definitely do not want one or the other behaviour would be great. – Kal Apr 15 '13 at 3:49
  • 2
    @Kal This would have to be a different question, since no answer here actually covers that. Edit : Actually, here it is : WHY a login shell over a non-login shell?. – Skippy le Grand Gourou Aug 14 at 13:15
up vote 259 down vote accepted

A login shell is the first process that executes under your user ID when you log in for an interactive 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 (e.g. -bash whereas it would normally be bash. Login shells typically read a file that does things like setting environment variables: /etc/profile and ~/.profile for the traditional Bourne shell, ~/.bash_profile additionally for bash, /etc/zprofile and ~/.zprofile for zsh, /etc/csh.login and ~/.login for csh, etc.

When you log in on a text console, or through SSH, or with su -, you get an interactive login shell. When you log in in graphical mode (on an X display manager), you don't get a login shell, instead you get a session manager or a window manager.

It's rare to run a non-interactive login shell, but some X settings do that when you log in with a display manager, so as to arrange to read the profile files. Other settings (this depends on the distribution and on the display manager) read /etc/profile and ~/.profile explicitly, or don't read them. Another way to get a non-interactive login shell is to log in remotely with a command passed through standard input which is not a terminal, e.g. ssh example.com <my-script-which-is-stored-locally (as opposed to ssh example.com my-script-which-is-on-the-remote-machine, which runs a non-interactive, non-login shell).

When you start a shell in a terminal in an existing session (screen, X terminal, Emacs terminal buffer, a shell inside another, etc.), you get an interactive, non-login shell. That shell might read a shell configuration file (~/.bashrc for bash invoked as bash, /etc/zshrc and ~/.zshrc for zsh, /etc/csh.cshrc and ~/.cshrc for csh, the file indicated by the ENV variable for POSIX/XSI-compliant shells such as dash, ksh, and bash when invoked as sh, $ENV if set and ~/.mkshrc for mksh, etc.).

When a shell runs a script or a command passed on its command line, it's a non-interactive, non-login shell. Such shells run all the time: it's very common that when a program calls another program, it really runs a tiny script in a shell to invoke that other program. Some shells read a startup file in this case (bash runs the file indicated by the BASH_ENV variable, zsh runs /etc/zshenv and ~/.zshenv), but this is risky: the shell can be invoked in all sorts of contexts, and there's hardly anything you can do that might not break something.

I'm simplifying a little, see the manual for the gory details.

  • 2
    Could you give example how to run bash as a non-interactive login shell? – Piotr Dobrogost Jun 16 '13 at 8:47
  • 10
    @PiotrDobrogost echo $- | bash -lx – Gilles Jun 16 '13 at 12:11
  • 1
    I don't know if this is true in general, but I want to note that when I open a new terminal (on osx using default settings), I get a login shell even though I never type in my username or password. – Kevin Wheeler Aug 28 '15 at 22:55
  • 2
    @KevinWheeler On OSX, by default, the Terminal application runs a login shell. (As I explain, the program that starts the shell decides whether the shell acts as a login shell.) That's not the normal way to do things. – Gilles Aug 28 '15 at 23:01
  • 2
    @IAmJulianAcosta If FOO is an environment variable (i.e. .profile contains export FOO=something) then it's available to all subprocesses, including foo.sh. If you change .profile to export FOO=something_else then ./foo.sh will still print something until the next time you log in. – Gilles Oct 6 '16 at 15:13

To tell if you are in a login shell:

prompt> echo $0
-bash # "-" is the first character. Therefore, this is a login shell.

prompt> echo $0
bash # "-" is NOT the first character. This is NOT a login shell.

Information can be found in man bash (search for Invocation). Here is an excerpt:

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

You can test this yourself. Anytime you SSH, you are using a login shell. For Example:

prompt> ssh user@localhost
fervor@localhost's password:
prompt> echo $0
-bash

The importance of using a login shell is the any settings in /home/user/.bash_profile will get executed. Here is a little more information if you are interested (from man bash)

"When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable. The --noprofile option may be used when the shell is started to inhibit this behavior."

In a login shell, argv[0][0] == '-'. This is how it knows it's a login shell.

And then in some situations it behaves differently depending on its "login shell" status. E.g. a shell, that is not a login shell, would not execute a "logout" command.

  • 4
    According to man bash, with emphasis added, "A login shell is one whose first character of argument zero is a -, or one started with the --login option." – Wildcard Jan 23 '17 at 11:49

A shell started in a new terminal in a GUI would be an interactive non-login shell. It would source your .bashrc, but not your .profile, for example.

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.