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.
.profileor equivalents), and 2. It's the shell that's supposed to started at login for a user, as defined in/etc/passwdor equivalent.$SHELLcontains the latter, yourshoptoutputs deal with the former. Typically, when the shell in (2) is started at login, it is started in the specific way needed for (1), hence the conflation of meanings. – muru Nov 25 '16 at 10:40$SHELL(and connect it to a pseudo terminal) which in turn is defined in your /etc/passwd entry. this shell is a login shell and can be tested withif [[ -o login ]]; then echo "I am a login shell"; fi. being a login shell it would perform those tasks appropriate to a new session. e.g. source~/.zprofileor similar which would possibly set environment variables and any custom shell code you might want to run at this time – the_velour_fog Nov 25 '16 at 11:17