Ich habe festgestellt, dass beim Ausführen eines Befehls direkt auf einem SSH-Host mithilfe der ssh <host> <command>
Syntax .bashrc
die Ausgabe von .bash_profile
(oder .profile
) angezeigt wird, jedoch nicht die Ausgabe von (oder ).
Wenn ich zum Beispiel den folgenden Befehl oben in beiden Dateien platziere,
echo ${BASH_SOURCE[0]}
und manuell Quelle .bash_profile
(welche Quellen .bashrc
wiederum), werde ich sehen
$ . .bash_profile
.bash_profile
.bashrc
Dies ist die gleiche Ausgabe, die ich sehe, wenn ich mich über SSH mit ssh <host>
der Befehlsform remote bei diesem Computer anmelde . (Und wenn ich .bash_profile
vorübergehend woanders verstaue , wird keine dieser Zeilen wiedergegeben.)
Wenn ich jedoch einen Befehl mit der ssh <host> <command>
Form von direkt auf dem Remotecomputer ausführe ssh
, sieht die Ausgabe folgendermaßen aus:
$ ssh <host> echo foo
/home/rlue/.bashrc
foo
Mein Verständnis ist, dass der Unterschied zwischen .bash_profile
und darin .bashrc
besteht, dass Ersteres für Login-Shells gilt, während Letzteres für interaktive Nicht-Login-Shells gilt .
Ich habe folgendes festgestellt:
ssh <host>
Quellen nur.bash_profile
, währendssh <host> <command>
nur Quellen.bashrc
, was bedeutet- Ersteres ist eine Login-Shell und Letzteres nicht.
Sind diese Schlussfolgerungen richtig? Warum wird ssh <host> <command>
es als interaktive Shell ohne Anmeldung behandelt? Meldet sich SSH nicht immer noch auf dem Remotecomputer an, um den Befehl auszuführen?
.bashrc
? Diese Datei soll keine Ausgabe erzeugen. Jede Ausgabe von.bashrc
kann alle Tools beschädigen, die ssh als Transport verwenden..bashrc
warfen einige Zeilen einen Fehler aus, ähnliche Zeilen.bash_profile
jedoch nicht. Ich nutzte die Gelegenheit, um die Diskrepanz zu untersuchen, bevor ich die störenden Linien reparierte.Antworten:
OpenSSH (höchstwahrscheinlich das, was Sie ausführen) entscheidet, ob eine Anmeldeshell erstellt werden soll oder nicht, und dies nur, wenn Sie keinen bestimmten Befehl ausführen. Von
man ssh
:Es ist also eine Implementierungsoption für den SSH-Server, ob er eine Anmeldeshell erstellen möchte oder nicht, und wenn Sie einen Befehl zum Ausführen geben, ist dies nicht der Fall.
Während Sie
ssh
eine Anmeldung durchführen, ist es viel ähnlicher, eine Shell zu erstellen, um diesen Befehl auszuführen, als eine Anmeldeumgebung abzurufen, wenn Sie einen Befehl ausführen und beenden. Angesichts dessen scheint es, dass die Leute, die OpenSSH schreiben, beschlossen haben, es wie eine solche Aufgabe zu behandeln.Sie erstellen eine nicht interaktive Shell ohne Anmeldung, um den Befehl auszuführen, da dies der Geist ist, einen Befehl in einem anderen Kontext / einer anderen Shell auszuführen. Normalerweise werden nicht interaktive Shells jedoch nicht automatisch als Quelle verwendet,
~/.bashrc
was hier eindeutig geschieht.bash
versucht tatsächlich, uns hier draußen zu helfen. Aus den Dokumentenquelle
ssh
eine Anmeldung erforderlich ist, haben die Implementierer anscheinend entschieden, dass unter bestimmten Umständen, z. B. wenn sie aufgefordert werden, einen Befehl auszuführen und zurückzukehren, dies getan wird Sie brauchen / profitieren nicht von den zusätzlichen Schritten, die eine Login-Shell ausführt, und überspringen diese. Es gibt also tatsächlich eine Shell, die ausgeführt wird. Ich gehe davon aus, dass die Umgebung hauptsächlich eingerichtet wird. Da die Shell dem angemeldeten Benutzer nicht zur Verfügung gestellt wird, wird sie so behandelt, als hätte der Benutzer gerade eine neue Shell gestartet, um diese auszuführen Befehlssh <host> <command>
die Umgebung keiner vorhandenen Anmeldeshell geerbt wird. Gibt beispielsweise$ ssh <host> \$PATH
den Pfad so zurück, wie er ohne Sourcing.bash_profile
(oder sozusagen.profile
) wäre ... Warum sollten Sie diesen Schritt praktisch umgehen?PATH
In.profile
- ist das nicht genau das, was Sie laden möchten, bevor Sie einen beliebigen Befehl auf einem Remote-Host ausführen?Das Warum dieses Verhaltens liegt auf einer niedrigeren Ebene als bei Shells:
ssh host
(der Fall "Login-Shell") verwendet ein Pseudoterminal auf dem Remote-Host, um zwischen demsshd
Serverprozess und der Shell zu kommunizieren .ssh host command
verwendet stattdessen Pipes zwischensshd
undcommand
. Pseudoterminals sind erforderlich, um einen Befehlsinterpreter wie eine Shell oder den " Read-Eval-Print " -Modus einer Skriptsprache interaktiv zu verwenden . Sie implementieren eine Reihe von benutzerfreundlichen Funktionen, z. B. die Möglichkeit, Tippfehler rückgängig zu machen. Sie haben jedoch einen höheren Overhead und lassen (abhängig von der Konfiguration) nicht zu, dass beliebige Daten unverändert übertragen werden. Daher vermeidet SSH die Verwendung dieser Daten, wenn keine Interaktion stattfinden soll.Manchmal macht SSHs Befehl / keine Befehlsheuristik dies falsch; Es kann mit den Schaltern
-t
und überschrieben-T
werden. Um sich beispielsweise bei einem Remotecomputer anzumelden und eine angehaltenescreen
Sitzung sofort wieder anzuschließen, müssen Sie Folgendes tunssh -t host screen -R
:ssh host screen -R
wird dazu führenscreen
, dass Sie sich beschweren, nicht an ein Terminal angeschlossen zu sein. Ich kann eine Situation nicht denken , wenn Sie tatsächlich würden wollen verwenden-T
, aber es ist da , wenn Sie jemals ein finden.quelle
Zuerst müssen Sie die verschiedenen Typen sehen, Sie können dies lesen:
/unix/170493/login-non-login-and-interactive-non-interactive-shells
Wenn Sie nun Ihren Bashrc öffnen, sehen Sie am Anfang Folgendes:
Das bedeutet, dass diese Datei je nachdem, wie Sie auf das System zugreifen, den Code darin lädt oder nicht.
quelle
.bashrc
Kann so geschrieben werden, dass sie nicht bezogen wird, wenn sie in einem nicht interaktiven Kontext aufgerufen wird ( dh wenn es keine „Eingabeaufforderung“ /$PS1
Variable gibt). Istssh <host> <command>
aber entschieden nicht interaktiv ; Das heißt, es wird keine Eingabeaufforderung ausgelöst. Warum sollte OpenSSH so konzipiert sein, dass.bashrc
für diesen scheinbar nicht angemeldeten, nicht interaktiven Anwendungsfall eine interaktive Eingabeaufforderung ohne Anmeldung (eine, die versucht, eine Quelle zu finden ) erstellt wird?