Where is the login shell defined?
TL;DR:
- Where is login shell defined? In
/etc/passwd
. - Are
sudo su
/sudo su -
/sudo -i
/sudo -s
same ? No, they all spawn a shell but differently and in different contexts. - What does
$SHELL
do? Just tell your default shell, same as in/etc/passwd
.
Actual Answer:
First of all, it's important to mention that shopt
is bash-specific. For instance, I am mksh
shell user, and it doesn't have shopt
, just like ksh
doesn't.
Next, what exactly login_shell
is supposed to represent ? From man bash
:
login_shell
The shell sets this option if it is started as a login shell
That's the key point. sudo -i
, as you already know from previous answer you read, is supposed to simulate initial login. That's why shopt
reports login_shell on
for this option. Think of this as if sudo -i
forces the shell to go through files that are supposed to appear only during a login process ( which don't get sourced by interactive shells).
In other cases, you already are running an instance of a shell, so it cannot be login shell in the first place, and the purpose of the options is different. sudo -s
merely reads $SHELL
(which is meant to represent your default shell as set in /etc/passwd
) variable and runs it with root privilege. This is equivalent to doing sudo $SHELL
or sudo mksh
or sudo bash
( whichever you happen to use).
Remember I mentioned that I am mksh
user ? Take a look at this:
$ bash --posix
bash-4.3$ sudo -s
[sudo] password for xieerqi:
DIR:/xieerqi|01:53|skolodya@ubuntu:
$ id
uid=0(root) gid=0(root) groups=0(root)
DIR:/xieerqi|01:53|skolodya@ubuntu:
$ echo $-
imsU
What you see is that sudo -s
jumped from bash
to my mksh
shell, with the characteristic prompt I've set for it. And of course, since it is not a login action, for bash
it would report that the shell is spawned as non - login shell instance. In my case, however, you see that $-
doesn't have a letter l
there, which would be there if that was a login shell instance.
Finally, the same idea applies to sudo su
and sudo su -
. Later one spawns login shell instance (i.e., specific files that are required for login will run) and former one spawns only interactive shells (i.e., login files don't run).
bash-4.3$ sudo su
[sudo] password for xieerqi:
root@eagle:/home/xieerqi# shopt login_shell
login_shell off
root@eagle:/home/xieerqi# exit
bash-4.3$ sudo su -
[sudo] password for xieerqi:
$ shopt login_shell
login_shell on
So technically, shopt login_shell
has no relation to $SHELL
whatsoever. Think of it this way: its purpose is to show how bash runs. $SHELL
is supposed to reflect only what you have assigned in /etc/passwd
.
As for the difference between login shell and non-login shell, it has been explained by highly-respected Gilles on unix.stackexchange.com in this answer.
Additional fun
Here's something fun you can try. As you may already know, a login shell will run .profile
(and .bashrc
since Ubuntu's .profile
is configured to do so) , but non-logins hell will run only .bashrc
file. So we can test with echo
which of these commands runs a login shell and which doesn't, and we expect two lines of echo
for login shell and only one for non-login.
$ echo "echo 'hi,i am .profile'" >> .profile
$ echo "echo 'hi, i am .bashrc'" >> .bashrc
$ sudo -i
hi, i am .bashrc
hi,i am .profile
$ sudo su
hi, i am .bashrc
root@eagle:~# sudo su -
hi, i am .bashrc
hi,i am .profile
$ sudo -s
hi, i am .bashrc
root@eagle:~#
Appropriately enough, those with two lines of output will have login_shell
set to on
.
As @Serg explains in this answer on how to tell what shell you are running, the SHELL
variable is just the current user's default shell as read from /etc/passwd
:
$ grep zanna /etc/passwd
zanna:x:1000:1000:Zanna,,,:/home/zanna:/bin/bash
so if I echo $SHELL
it will always return /bin/bash
:
$ zsh
% echo $SHELL
/bin/bash
Whether or not the shell is a login shell, is a shell option determined at the time the shell is started. The shell program stores this information along with all its other settings and variables. The shopt
command provides a way to see this information and, if possible for the option in question, to set or unset it (this isn't the case for login_shell
which, of course, depends on the process used to start the shell)
The sudo
program's options determine how these different types of root shell will be started: