Whats the Difference Between a Login and a Non-Login Shell?
I always kind of knew there was a difference between login and non-login shells, but when I couldn’t explain the difference properly to a coworker, I knew I needed to spend some time on figuring it out.
The difference is addressed nicely in the book Unix Power Tools (Oreilly):
When you first log in to a Unix system from a terminal, the system normally starts a login shell. A login shell is typically the top-level shell in the “tree” of processes that starts with the
initprocess. Many characteristics of processes are passed from parent to child process down this “tree” — especially environment variables, such as the search path. The changes you make in a login shell will affect all the other processes that the top-level shell starts — including any subshells.
So, a login shell is where you do general setup that’s done only the first time you log in — initialize your terminal, set environment variables, and so on. […]
So you could think about a login shell as a shell that is started at
startup by the
init process (or
systemd nowadays). Or as a shell
that logs you into the system by your providing a username and a
password. A non-login shell, by contrast, is a shell that is invoked
without logging anybody in.
Is My Current Shell a Login Shell?
There are two ways to check if your current shell is a login shell:
First, you can check the output of
echo $0: if it starts with a dash
-bash), it’s a login shell. Be aware, however, that you can
start a login shell with
bash --login, and
echo $0 will output just
bash without the leading dash, so this is not a surefire way of find
out if you are running a login shell.
Secondly, the Unix StackOverflow offers this way of finding out:
$ shopt -q login_shell && echo login || echo nonlogin
-q suppresses the output of the
The Difference Between Login and Non-Login That Actually Matters
Practically speaking, the difference between a login shell and a
non-login shell is in the configuration files that Bash reads when it
starts up. In particular, according to
[…] it first reads and executes commands from the file
/etc/profile, if that file exists. After reading that file, it looks for
~/.profile, in that order, and reads and executes commands from the first one that exists and is readable.
You can observe this behavior by putting
echo commands in
bash --login you should see:
echo from /etc/profile echo from ~/.bash_profile $
If the shell is a non-login shell, Bash reads and executes commands from
~/.bashrc. Since we are starting a non-login shell from within a login
shell, it will inherit the environment. Sometimes, this will lead to
confusion when we inadvertently get a login shell, and find out that our
~/.bashrc is not loaded. This is why many people
put something like the following in their
[[ -r ~/.bashrc ]] && source ~/.bashrc
This test whether
.bashrc is readable and then sources it.
Why You Sometimes Want a Login Shell
When you switch users using
su you will take the environment of the
calling user with you. To prevent this, you should use
su - which is
su --login. This acts like a clean login for a new user, so
the environment will not be cluttered with values from the calling user.
Just as before, a login shell will read
/etc/profile and the
.bash_profile of the user you are switching to, but not its
This post on
StackOverflow shows why
you might want to prefer to start with a clean environment (spoiler:
your $PATH might be “poisoned”).
In this article we saw that the main difference between a login and a non-login shell are the configuration files that are read upon startup. We then looked at what the benefits are of a login shell over a non-login shell.