Kann es eine Login-Shell geben, die nicht interaktiv ist?


11

Bei der Interpretation dieses Flussdiagramms

Geben Sie hier die Bildbeschreibung ein

Ich fand das in man bash:

Wenn bash als interaktive Anmeldeshell oder als nicht interaktive Shell mit der Option --login aufgerufen wird, werden zuerst Befehle aus der Datei / etc / profile gelesen und ausgeführt, sofern diese Datei vorhanden ist.

Das heißt, dass interaktive Login- Shells gelesen werden /etc/profile(ohne --noprofile)

Auch nicht interaktive Shells mit der Option --loginlesen/etc/profile

Das scheint einige mögliche Login- Shells zu hinterlassen (in denen das $0mit a beginnt -), die nicht interaktiv sind (ein Skript ausführen, vielleicht so einfach wie date), möglicherweise nicht gelesen werden (Quelle) /etc/profile.

Um diese Idee zu bestätigen oder abzulehnen:

Zuerst habe ich versucht su -l -, eine Login-Shell mit einem -als erstes Zeichen zu starten, aber ich kann sie nicht interaktiv machen (und in der Lage sein, die Tests zu präsentieren, um sie zu testen).

So etwas nennen

$ bash -c 'date' -bash

Gibt nicht an, eine Anmeldeshell zu sein (selbst wenn das erste Zeichen a ist -).

Versuchen Sie dies, um das Detail zu enthüllen:

   $ bash -c 'echo "$0 $- ||$(shopt -p login_shell)||";date' -bash
      -bash hBc ||shopt -u login_shell||
      Fri Aug 19 06:32:31 EDT 2016

Das $0hat ein -als erstes Zeichen, es gibt kein i(interaktives) im Wert von, $-aber es wird nicht als login_shell(das -u) gemeldet . In diesem Fall wurde / etc / profile nicht gelesen, aber ich bin nicht sicher, ob dies der richtige Test ist.


In dieser Antwort werden auch "seltene nicht interaktive Login-Shells" erwähnt , ohne für diese Frage spezifisch genug zu sein.


Die Schlussfolgerung dieses Typen ist, dass /etc/profileimmer gelesen wird.

Lesen Sie die Übersichtstabelle: Es werden sowohl interaktive als auch nicht interaktive Login-Shells gelesen /etc/profile


Und wenn die Beispiele auf dieser Seite korrekt sind:

Some examples

$ su bob                   # interactive non-login shell
$ su - bob                 # interactive login shell
$ exec su - bob            # interactive login shell
$ exec su - bob -c 'env'   # non-interactive login shell
$ ssh bob@example.com      # interactive login shell, `~/.profile`
$ ssh bob@example.com env  # non-interactive non-login shell, `~/.bashrc`

Der Test der gelesenen exec su - bob -c 'env'Berichte /etc/profile.


Zusamenfassend:

Ist es möglich, eine nicht interaktive Anmeldeshell zu haben (nicht mit --login oder -l aufgerufen)?

Und wenn ja, liest es die /etc/profileDatei?

Wenn das oben Gesagte zutrifft, müssen wir daraus schließen, dass ALLE Login-Shells [interaktiv (oder nicht)] / etc / profile (ohne --noprofileOption) lesen .

Hinweis: Um festzustellen, dass / etc / profile gelesen wird, fügen Sie einfach ganz am Anfang der Datei diesen Befehl hinzu:

echo "'/etc/profile' is being read"

Antworten:


2

Eine nicht interaktive Login-Shell ist ungewöhnlich, aber möglich. Wenn Sie die Shell mit dem nullten Argument (normalerweise der Name der ausführbaren Datei) starten, das auf eine Zeichenfolge gesetzt ist, die mit a beginnt -, handelt es sich um eine Anmeldeshell, unabhängig davon, ob sie interaktiv ist oder nicht.

$ ln -s /bin/bash ./-bash
$ echo 'shopt -p login_shell; echo $-' | HOME=/none PATH=.:$PATH -bash
shopt -s login_shell
hB

Ihr Versuch bash -c date -bashhat nicht funktioniert, da die Shell dadurch nicht als Anmeldeshell bezeichnet wird: Das nullte Argument ist bashnicht -bash. Nachdem bash gestartet wurde, setzt es die Variable $0auf -bashanstelle des nullten Arguments, aber das nullte Argument ist wichtig.

Sie können eine nicht interaktive Anmeldeshell mit su -loder ausführen su -, müssen jedoch dafür sorgen, dass die Standardeingabe kein Terminal ist, während Sie dennoch autorisiert werden können (ohne ein Kennwort eingeben zu müssen oder Ihr Kennwort am Anfang des zu haben Eingang). Mit sudo: run kann es einfacher sein sudo true, einen Anwesenheitsnachweis abzurufen, und solange der Berechtigungsnachweis noch gültig ist, wird ausgeführt echo 'shopt -p login_shell; echo $-' | sudo -i.

Siehe auch Unterschied zwischen Login-Shell und Nicht-Login-Shell?


4

Ich habe grafische Anmeldeumgebungen gesehen, die Folgendes tun:

exec "$SHELL" -l -c 'exec start-window-or-session-manager'

oder das Äquivalent von:

exec -a "-$SHELL" "$SHELL" <<EOF
exec start-window-or-session-manager
EOF

Damit die Sitzungsinitialisierungsdatei (wie ~/.profilefür Bourne-ähnliche Shells (und die entsprechenden /etcfür einige)) gelesen und angewendet wird.

Der erste funktioniert nicht mit allen Muscheln. -lwird von einer großen Anzahl von Shells unterstützt, aber nicht von allen, und auf einigen, wie csh/ tcsh, kann nicht mit verwendet werden -c. Das erste Zeichen des argv[0]Seins -wird jedoch von allen Shells verstanden, da dies loginverwendet wird, um den Shells zu sagen , dass es sich um Login-Shells handelt.

Im zweiten Fall ist der Standard dieser Shell etwas anderes als ein ttyGerät ( <<wird durch eine temporäre reguläre Datei oder eine Pipe abhängig von der Shell implementiert), sodass die Shell nicht interaktiv ist (die Definition des interaktiven Wesens, wenn ein Mensch interagiert damit).


Der erste verwendet die --loginOption. Für das zweite, wenn ich es exec -a "-bash" "bash" <<<"shopt -p login_shell; echo $0 $-"bekomme (in C qoutes codiert) $'/etc/profile read\nshopt -s login_shell\nbash himBH', ist es Login, aber es ist interaktiv. Wir brauchen Login und nicht interaktiv . Was fehlt mir?

@sorontar, with <<<"$-", das $-durch die aufrufende Shell aufgrund der doppelten Anführungszeichen erweitert wird. Die aufgerufene Shell ist nicht interaktiv, da ihre stdin keine tty ist.
Stéphane Chazelas

Ah ja, Sie haben Recht, Sir. Um den Fehler zu korrigieren, können wir jedoch Folgendes tun: exec -a "-bash" "bash" <<\EOF shopt -p login_shell; echo $0 $- EOFUm diese Bestätigung zu erhalten: $'/etc/profile read stdin: is not a tty shopt -s login_shell -bash hB'Ja, eine nicht interaktive Anmeldeshell ist möglich und wird weiterhin gelesen /etc/profile. Sollten wir daraus schließen, dass ALLE Login-Shells gelesen werden /etc/profile?

ksh macht ziemlich deutlich, dass es sich um eine nicht interaktive Login-Shell handelt , versuchen Sie es exec -a "-ksh" "ksh" <<\EOF echo $0; set -o EOF:).

1
@sorontar, ich denke, Sie können erwarten, dass die meisten Shell-Implementierungen ihre Sitzungsinitialisierungsdatei (en) lesen, wenn sie als Login-Shells aufgerufen werden. Was sie sind, hängt von der Shell-Implementierung und -Version ab. Im Fall von bash, die Handhabung der Startdatei ist IMO ziemlich durcheinander. Sie werden feststellen, dass einige Systeme sie gepatcht haben, um ein vernünftigeres Verhalten zu erzielen und noch mehr Variationen hinzuzufügen.
Stéphane Chazelas

3

Ja, nicht interaktive Login-Shells sind möglich

$ head -1 /etc/profile
echo PROFILE BEING READ

$ echo echo hello | su -
PROFILE BEING READ
stdin: is not a tty
hello

$

Das ist ähnlich vereinfacht : su -c 'echo hello' -. su -c 'echo $0 $-; shopt -p login_shell' -Um zu testen, was wir brauchen, sollte Folgendes geschrieben werden: um diese bestätigende Antwort zu erhalten (in C-Anführungszeichen kodiert) : $'/etc/profile read \n -su hBc \n shopt -s login_shell'. Dies bestätigt, dass eine nicht interaktive Login - Shell ausgeführt wurde und dabei / etc / profile gelesen wurde. Vielen Dank.

0

Ist es möglich, eine nicht interaktive Anmeldeshell zu haben (nicht mit --login oder -l aufgerufen)?

JA.

$ (exec -a '-' bash -c 'shopt -q login_shell && echo login shell')

Beachten Sie jedoch, dass /etc/profiledies nicht für eine nicht interaktive Anmeldeshell verwendet wird, wenn das --loginArgument nicht angegeben wird.

Eine gebräuchliche Redewendung, die eine nicht interaktive Anmeldeshell aufruft, ist:

$ su - someuser -c somecommand

Dies leidet jedoch unter der Tatsache, dass /etc/profilenicht ausgeführt wird.

Es ist möglich, dieses Verhalten zu ändern, aber es umfasst das Anpassen des Bash-Quellcodes zur Kompilierungszeit, indem eine in config-top.h gefundene Option auskommentiert wird :

/* Define this to make non-interactive shells begun with argv[0][0] == '-'
run the startup files when not in posix mode. */
/* #define NON_INTERACTIVE_LOGIN_SHELLS */

Als ich diese suAnomalie untersuchte , stellte ich fest, dass andere Muscheln diese Diskrepanz enthalten zshund dashnicht aufweisen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.