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.