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.