Wo ist die Login-Shell definiert?

16

Ich habe den Unterschied zwischen sudo -i/-s hier gelesen . Nach der Verwendung des Befehls shoptwird festgestellt, dass all ( sudo su/sudo -i/sudo -s) die $SHELLgleichen Ergebnisse liefern, die shoptBefehlsergebnisse jedoch unterschiedlich sind.

Also, wie ist Login und Nicht-Login-Shell definiert?

Von dort , wo shoptdas Ergebnis erhalten?

Warum ist es nicht verwandt mit $SHELL?

sudo su

givinv@87-109:~$ sudo su
root@87-109:/home/givinv# 
root@87-109:/home/givinv# 
root@87-109:/home/givinv# shopt -q login_shell && echo 'Login shell' || echo 'No login shell'
No login shell
root@87-109:/home/givinv# echo $SHELL
/bin/bash
root@87-109:/home/givinv# 
root@87-109:/home/givinv# exit
givinv@87-109:~$ 

sudo -i

givinv@87-109:~$ sudo -i
root@87-109:~# 
root@87-109:~# shopt -q login_shell && echo 'Login shell' || echo 'No login shell'
Login shell
root@87-109:~# echo $SHELL
/bin/bash
root@87-109:~# 

sudo -s

root@87-109:~# sudo -s
root@87-109:~# shopt -q login_shell && echo 'Login shell' || echo 'No login shell'
No login shell
root@87-109:~# echo $SHELL
/bin/bash
root@87-109:~# 
Prado
quelle
7
Ein Problem ist, dass "Login-Shell" zwei Bedeutungen hat: 1. Es handelt sich um eine Instanz einer Shell, die auf eine bestimmte Art und Weise gestartet wurde und bestimmte Aufgaben ausführt (z. B. Lesen .profileoder Äquivalente) Benutzer, wie in /etc/passwdoder gleichwertig definiert . $SHELLEnthält die letztere, beschäftigen sich Ihre shoptAusgaben mit der ersteren. Wenn die Shell in (2) bei der Anmeldung gestartet wird, wird sie in der Regel auf die für (1) erforderliche Art und Weise gestartet, sodass die Bedeutungen zusammengeführt werden.
Muru
1
@murus Erklärung ist gut. Zum Beispiel, wenn Sie SSH von einem entfernten Computer in Ihren Computer einbinden. / usr / sbin / sshd auf Ihrem System würde eine Shell, die durch $SHELL(und verbinden Sie es mit einem Pseudo-Terminal) definiert ist, verzweigen, die wiederum in Ihrem / etc / passwd-Eintrag definiert ist. Diese Shell ist eine Login-Shell und kann mit getestet werden if [[ -o login ]]; then echo "I am a login shell"; fi. Als Anmeldeshell würde es die Aufgaben ausführen, die für eine neue Sitzung geeignet sind. zB source ~/.zprofileoder ähnliches, das möglicherweise Umgebungsvariablen und benutzerdefinierten Shell-Code setzt, den Sie zu diesem Zeitpunkt
ausführen

Antworten:

17

TL; DR :

  • Wo ist die Login-Shell definiert? In /etc/passwd.
  • Sind sudo su/ sudo su -/ sudo -i/ sudo -sgleich? Nein, sie alle spawnen eine Shell, aber anders und in unterschiedlichen Kontexten.
  • Was macht $SHELLdas? Sagen Sie einfach Ihre Standard-Shell, wie in /etc/passwd.

Tatsächliche Antwort :

Zuallererst ist es wichtig zu erwähnen, dass dies shoptbash-spezifisch ist. Zum Beispiel bin ich mkshShell-Benutzer, und es hat nicht shopt, genau wie kshnicht.

Was genau login_shellsoll als nächstes dargestellt werden? Von man bash:

login_shell

Die Shell setzt diese Option, wenn sie als Login-Shell gestartet wird

Das ist der entscheidende Punkt. sudo -isoll, wie Sie bereits aus der vorherigen Antwort wissen, die erstmalige Anmeldung simulieren. Aus diesem Grund shoptwird login_shell on für diese Option berichtet. Stellen Sie sich das so vor, als würde sudo -idie Shell dazu gezwungen, Dateien zu durchsuchen, die nur während eines Anmeldevorgangs angezeigt werden sollen (die nicht von interaktiven Shells bezogen werden).

In anderen Fällen führen Sie bereits eine Instanz einer Shell aus, sodass es sich nicht in erster Linie um eine Anmeldeshell handeln kann, und der Zweck der Optionen ist unterschiedlich. sudo -sLiest lediglich $SHELLdie /etc/passwdVariable (die Ihre Standard-Shell darstellen soll, wie sie in festgelegt ist ) und führt sie mit Root-Rechten aus. Dies entspricht tun sudo $SHELLoder sudo mkshoder sudo bash(je nachdem , was Sie verwenden passieren).

Erinnerst mkshdu dich, dass ich erwähnt habe, dass ich ein Benutzer bin ? Schau dir das an:

$ 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

Was Sie sehen, ist, dass es in meine Muschel sudo -sgesprungen ist , mit der charakteristischen Eingabeaufforderung, die ich dafür festgelegt habe. Und da es sich natürlich nicht um eine Anmeldeaktion handelt, wird gemeldet, dass die Shell als Nicht-Anmeldeshellinstanz erstellt wurde. In meinem Fall sehen Sie jedoch, dass dort kein Buchstabe vorhanden ist, der vorhanden wäre, wenn dies eine Login-Shell-Instanz wäre.bashmkshbash$-l

Letztendlich gilt der gleiche Gedanke für sudo suund sudo su -. Später wird eine Login-Shell-Instanz erzeugt (dh, bestimmte Dateien, die für die Anmeldung erforderlich sind, werden ausgeführt), und erstere erzeugt nur interaktive Shells (dh, Anmeldedateien werden nicht ausgeführt).

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

Also technisch shopt login_shellhat das überhaupt nichts zu $SHELLtun. Stellen Sie es sich so vor: Es soll zeigen, wie bash ausgeführt wird. $SHELLsoll nur widerspiegeln, was Sie in zugewiesen haben /etc/passwd.

Der Unterschied zwischen Anmelde-Shell und Nicht-Anmelde-Shell wurde in dieser Antwort von hoch angesehenem Gilles auf unix.stackexchange.com erklärt .


Zusätzlicher Spaß

Hier ist etwas Spaß, den Sie ausprobieren können. Wie Sie vielleicht bereits wissen, wird eine Login-Shell ausgeführt.profile (und .bashrcda Ubuntu .profile dafür konfiguriert ist ), aber Nicht-Logins werden nur .bashrcDateien ausgeführt. Wir können also testen, mit echowelchem ​​dieser Befehle eine Login-Shell ausgeführt wird und mit welchem ​​nicht. Wir erwarten zwei Zeilen echofür die Login-Shell und nur eine für die Nicht-Login-Shell.

$ 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:~# 

Passenderweise haben diejenigen mit zwei Ausgabezeilen auf login_shellgesetzt on.

Sergiy Kolodyazhnyy
quelle
Vielen Dank an Serg und Zanna. Nun zu $SHELLund login_shell/non-login_shellwurde geklärt. Aber woher shoptbekommen Details? Ist es von echo $0?
Prado
1
@prado Ich würde ja sagen, da das erste Zeichen von $0verwendet wird, um anzugeben, ob eine Shell eine Anmeldeshell ist oder nicht. Wenn shoptSie also diese Variable prüfen würden, ist dies absolut akzeptabel. Es gibt jedoch wahrscheinlich mehr als das, was man sieht. shoptWahrscheinlich habe ich für diese Frage keine eindeutige Antwort, da ich mit Bashs Quellcode nicht so gut vertraut bin.
Sergiy Kolodyazhnyy
@prado Bash kann als Anmeldeshell entweder mit dem ersten Zeichen von $ 0 -oder mit der -lOption gestartet werden .
Muru
@prado Informationen zu Aufruf und Optionen von bash finden Sie in der Manpage. Im Abschnitt SHELL BUILTIN COMMAND heißt es beispielsweise, login_shell The shell sets this option if it is started as a login shell (see INVOCATION above). The value may not be changed.dass Sie mit der shopt login_shellEinweg-Bash programmgesteuert herausfinden können, wie sie gestartet wurde. der andere Weg wäre[[ -o login ]]
the_velour_fog
11

Wie @Serg in dieser Antwort erklärt, um festzustellen , welche Shell Sie ausführen , ist die SHELLVariable nur die Standardeinstellung des aktuellen Benutzers Shell wie sie gelesen wird von /etc/passwd:

$ grep zanna /etc/passwd
zanna:x:1000:1000:Zanna,,,:/home/zanna:/bin/bash

also wenn ich echo $SHELLes immer wiederkomme/bin/bash :

$ zsh
% echo $SHELL
/bin/bash

Unabhängig davon , ob die Hülle ein Login - Shell ist ein sh ell opt Ion zu dem Zeitpunkt bestimmt die Shell gestartet wird. Das Shell-Programm speichert diese Informationen zusammen mit allen anderen Einstellungen und Variablen. Der shoptBefehl bietet eine Möglichkeit, diese Informationen anzuzeigen und, falls möglich, für die betreffende Option zu aktivieren oder zu deaktivieren (dies ist jedoch nicht der Fall, login_shellwas natürlich vom Prozess abhängt, der zum Starten der Shell verwendet wird).

Die sudoOptionen des Programms bestimmen, wie diese verschiedenen Arten von Root-Shell gestartet werden:

Bildbeschreibung hier eingeben

Zanna
quelle
1
Gute Erklärung. Ich denke du hast was erklärt shoptund login_shellsollst das in meiner Antwort weitaus besser darstellen.
Sergiy Kolodyazhnyy
@ Serg danke :) Ich denke, Ihre Erklärung ist gründlicher :)
Zanna
3

man bash:

Eine Login-Shell ist eine Shell, deren erstes Zeichen des Arguments Null ein ist -, oder eine Shell , die mit der --loginOption gestartet wurde .

man login:

Der Wert für $HOME, $SHELL[...] wird entsprechend den entsprechenden Feldern in der Passworteingabe festgelegt.

Zusamenfassend:

  • Eine Shell ist eine Anmeldeshell, wenn sie als Anmeldeshell aufgerufen wurde.
  • Die Umgebungsvariable $SHELLwird loginzum Beispiel von oder durch das aufrufende Programm festgelegt su. Die Shell selbst setzt es nicht.
  • shopt Zeigt die aktuell gültigen Shell-Optionen an.
AlexP
quelle