I have a basic understanding of dotfiles in *nix system. But I am still quite confused about this Difference between Login Shell and Non-Login Shell?

A bunch of different answers (including multiple duplicates) have already addressed the following bullets:

  • How to invoke a login or non-login shell
  • How to detect a login or non-login shell
  • What startup files will be consumed by a login or non-login shell
  • Referred to documentation (e.g., man bash) for more details

What the answers didn't tell (and also something I'm still confused about) is:

  • What is the use case of a login or non-login shell? (e.g., I only configured zshrc for zsh and that's enough for most personal dev requirement, I know it's not as simple as what vimrc to vim)

  • What is the reason to use a login over a non-login shell (besides consuming different startup files & life cycles)?


The idea is that a user should have (at most) one login shell per host.  (Perhaps I should say, one login shell per host per terminal — if you are simultaneously logged in to a host through multiple terminals, you would expect to have multiple login shells.)  This would typically (always?) be the first shell you get upon logging in (hence the name).  So, this scheme allows you to specify actions that you want to happen only once per login and things that you want to happen every time you start a new (interactive) shell.

Normally, every other shell you run after logging in will be a descendant (a child of a child of a child …) of the login shell, and therefore will inherit many settings (environment variables, umask, etc.) from the login shell.  And, accordingly, the idea is that the login initialization files (.login, .profile, etc.) should set the settings that are inheritable, and let .bashrc (or whatever else you use) handle the ones that aren’t (set, shopt, non-exported shell variables, etc.)

Another notion is that the login initialization files (and only they) should do “heavy lifting”, i.e., resource-intensive actions.  For example, you might want to have certain processes running in the background whenever you’re logged in (but only one copy (instance) of them).  You might want to have some status information (e.g., df or who) displayed when you login, but not every time you start a new interactive shell.  Especially if you have an interactive program/dialog (i.e., one that demands input from you) that you want to run every time you login, you probably don’t want to have it run every time you start a new shell.  As an extreme example, twenty years ago Solaris logged you in to a single, non-graphical, non-windowed shell.  (I believe that it has changed since then.)  It was the job of .login or .profile (or whatever) to start the windowing system, with a command like startx.  (This was useful partly because there were multiple windowing systems available.  Different users had different preferences.  Some users used different systems in different situations, and we had a dialog in our .profile that asked “Which windowing system do you want to use today?”)  Obviously, you wouldn’t want that to run every time you opened a new window or typed sh.

It’s been ages since I’ve used anything other than bash except for edge cases.  (For example, I write scripts with #!/bin/sh, so on some systems, my scripts run with dash, and on others they run with bash in POSIX mode.  A few times a year I run csh/tcsh for a few minutes to see how it handles something, or to answer a question.)  If you use multiple shells (e.g., bash and zsh) on a daily basis, your patterns may be different.  If your primary shell (as defined in /etc/passwd) is bash, you might want to invoke a zsh login shell, and then perhaps invoke some interactive non-login zsh shells subordinate to that.  You should probably avoid having a login shell that is subordinate to another login shell of the same type.

As mentioned in Difference between Login Shell and Non-Login Shell?, the OS X Terminal application runs a login shell, so a typical user will typically have several “login shells” running simultaneously.  This is a somewhat different model from the one I have described above, and may require the user to rethink what he does in his .login or .profile (or whatever) file.  I don’t know whether the OS X developers have documented their rationale for this design decision.  But I can imagine a situation in which this would be useful.  There was a time when I habitually opened a handful of shell windows when I logged in, and I would set them to different text and background colors (by writing ANSI escape sequences to the screen) to help me keep track of which was which.  Terminal colors are an example of something that is not inherited by children-of-children, but does persist within a window.  So this is the sort of thing that you would want to do every time you started a new Terminal window, but not every time you start a new interactive shell.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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