Warum bezieht Remote-Bash .bash_profile anstelle von .bashrc

24

Bash Manual sagt:

Bash versucht zu bestimmen, wann es mit seiner Standardeingabe ausgeführt wird, die mit einer Netzwerkverbindung verbunden ist, wie es vom Remote-Shell-Dämon rshd oder vom Secure-Shell-Dämon sshd ausgeführt wird. Wenn Bash feststellt, dass es auf diese Weise ausgeführt wird, liest es Befehle von ~ / .bashrc und führt sie aus, sofern diese Datei vorhanden und lesbar ist.

Diese Bash-Quellen ~/.bashrc:

ssh user@host :

Aber diese Bash-Quellen ~/.bash_profile:

ssh user@host

Ich sehe keinen Unterschied in diesen beiden Befehlen gemäß der Spezifikation. Ist stdin nicht in beiden Fällen mit einer Netzwerkverbindung verbunden?

Cyker
quelle
2
Es ist zwar nicht das, wonach Sie fragen, aber es wird empfohlen, .bashrc aus .bash_profile zu beziehen . Auf diese Weise werden die Einstellungen von .bashrc angewendet, unabhängig davon, ob bash als Anmeldeshell oder als Nicht-Anmeldeshell gestartet wird.
Ilmari Karonen

Antworten:

44

Eine Login-Shell liest zuerst /etc/profileund dann ~/.bash_profile.

Eine Nicht-Login-Shell liest von /etc/bash.bashrcund dann ~/.bashrc.

Warum ist das so wichtig?

Wegen dieser Zeile in man ssh:

Wenn ein Befehl angegeben wird, wird er auf dem Remote-Host anstelle einer Anmeldeshell ausgeführt.

Mit anderen Worten, wenn der Befehl ssh nur Optionen enthält (kein Befehl), wie zum Beispiel:

ssh user@host

Es wird eine Login-Shell gestartet, eine Login-Shell liest ~/.bash_profile.

Ein ssh-Befehl, der einen Befehl hat , wie:

ssh user@host :

Wo der Befehl ist :(oder nichts tun).
Es wird keine Login-Shell gestartet, daher ~/.bashrcwird gelesen.


Remote stdin

Die angegebene tty-Verbindung für / dev / stdin auf dem Remotecomputer ist möglicherweise eine tatsächliche tty oder etwas anderes.

Zum:

$ ssh sorontar@localhost
/etc/profile sourced

$ ls -la /dev/stdin
lrwxrwxrwx 1 root root 15 Dec 24 03:35 /dev/stdin -> /proc/self/fd/0

$ ls -la /proc/self/fd/0
lrwx------ 1 sorontar sorontar 64 Dec 24 19:34 /proc/self/fd/0 -> /dev/pts/3

$ ls -la /dev/pts/3
crw--w---- 1 sorontar tty 136, 3 Dec 24 19:35 /dev/pts/3

Was in einem TTY (keine Netzwerkverbindung) endet, wie die gestartete Bash es sieht.

Für eine SSH-Verbindung mit einem Befehl:

$ ssh sorontar@localhost 'ls -la /dev/stdin'
sorontar@localhost's password: 
lrwxrwxrwx 1 root root 15 Dec 24 03:35 /dev/stdin -> /proc/self/fd/0

Die Liste der TTYs beginnt gleich, aber beachten Sie, dass / etc / profile nicht bezogen wurde.

$ ssh sorontar@localhost 'ls -la /proc/self/fd/0'
sorontar@localhost's password:
lr-x------ 1 sorontar sorontar 64 Dec 24 19:39 /proc/self/fd/0 -> pipe:[6579259]

Das sagt der Shell, dass die Verbindung eine Pipe ist (keine Netzwerkverbindung).

In beiden Testfällen kann die Shell also nicht wissen, dass die Verbindung von einem Netzwerk stammt, und liest daher nicht ~/.bashrc(wenn wir nur über die Verbindung zu einem Netzwerk sprechen). Es liest ~ / .bashrc, aber aus einem anderen Grund.

Sorontar
quelle
Wäre der No-Arg-Fall nicht auch dazu geeignet , mit seiner Standardeingabe an eine Netzwerkverbindung angeschlossen und damit ~/.bashrcgelesen zu werden?
Cyker
@ Cyker Das setzt voraus, dass die Shell stdin mit einem Netzwerk verbunden ist . Warum nimmst du das an? (Antwort bearbeitet, bitte lesen).
Sorontar
Der bearbeitete Teil ist interessant. Sieht so aus, als würde sich ssh nicht um ein Pty kümmern, wenn man einfach einen Befehl ausführt.
Cyker
8

Sie fragen nach dem "Warum" und nicht nach dem "Wie", also werde ich versuchen, aus dieser Perspektive zu antworten. Das Folgende ist eine gute Begründung dafür, warum Dinge in der Vergangenheit passiert sind und wie sie heute passieren.


Der Grund für die Verwendung von zwei verschiedenen Startdateien ("profile" und "rc") war, dass in der Vergangenheit die Arbeitsweise auf einem Computer häufig war:

  1. Loggen Sie sich von einem echten Terminal oder einer anderen Workstation aus ein und erhalten Sie eine Login-Shell . Diese Shell ruft die Umgebung für den Benutzer auf /etc/profileund ~/.profilerichtet sie ein.

  2. Rufen Sie die Umgebung auf, in die der Benutzer eintreten möchte. Diese Umgebung könnte Xorg sein, aber in den meisten Fällen handelte es sich um einen Multiplexer wie GNU Screen.

  3. Die Umgebung (zB GNU-Bildschirm) würde dann zusätzliche (Nicht-Login-) Shells aufrufen, die die Umgebung von der übergeordneten Login-Shell erben.

Das war der gemeinsame Weg in einer UNIX - Maschine der Protokollierung während der Zeit, cshund bashentwickelt wurden. Daher wurde es als verschwenderisch~/.profile empfunden, die die Umwelt vererbenden Muscheln noch einmal zu lesen .

bashdann ~/.bashrcfür zusätzliche Konfiguration für diese nicht-Login-Shells hinzugefügt . csh(und tcsh) haben niemals irgendeine Art von "rc" -Datei für nicht angemeldete Shells hinzugefügt. Beachten Sie, dass csh/ tcshkeine Shells sind, die mit der Bourne-Shell (die Teil von POSIX ist) kompatibel sind, solange sie sich in einem Zustand bashbefindet. Eine andere bourne-kompatible Shell kshfügte eine Umgebungsvariable (aufgerufen ENV) hinzu, die, falls definiert, als Ausführungsbefehlsdatei ("rc") für nicht angemeldete Benutzer verwendet wird ksh.

Ja, neuere Versionen von bourne-Shells haben die zusätzliche Konfigurationsdatei hinzugefügt, um Aliase und andere schnelle Optionen zu vereinfachen, die in den Shells vorhanden sind, die vom GNU-Bildschirm (oder ähnlichem) gemuxt werden, aber nicht in der Shell enthalten sind, die Sie beim ersten Aufrufen von erhalten Maschine.

Mit der Einführung von Grafik-Display-Managern (GDMs) wurde die Unterscheidung zwischen "profile" -Dateien und "rc" -Dateien bedeutungslos, da das GDM über eigene Initialisierungsdateien (z . B. ~/.xinitund ~/.xsession) verfügen würde . Dann können Shells, die innerhalb des GDM angegeben werden, Anmelde- oder Nicht-Anmelde-Shells sein, abhängig von den Launen eines Benutzers, und der Fall, in dem eine Nicht-Anmelde-Shell immer ein übergeordnetes Element hat, das eine Anmelde-Shell ist, ist nicht mehr wahr.

Extra

Eine meiner Lieblingstabellen zum Vergleich von Shell-Startdateien zeigt, wie bourne-Shell-kompatible Shells die profileDateien verwenden, während andere Shells dies nicht tun . Dies liegt daran, dass in der Vergangenheit die ursprüngliche Shell (diejenige, die den Muxer gestartet hat) eine Borowski-kompatible Shell sein musste.

grochmal
quelle