OpenSSH (höchstwahrscheinlich das, was Sie ausführen) entscheidet, ob eine Login-Shell erstellt wird oder nicht, und dies nur, wenn Sie keinen bestimmten Befehl ausführen. Ab man ssh
:
If command is specified, it is executed on the remote host instead of a login shell.
Es ist also eine Implementierungsentscheidung für den SSH-Server, ob er eine Login-Shell erstellen möchte oder nicht, und wenn Sie einen Befehl zum Ausführen geben, tut er dies nicht.
Während ssh
eine Anmeldung durchführt, wenn Sie einen Befehl ausführen und beenden lassen, ist es wirklich viel ähnlicher, eine Shell zu erstellen, nur um diesen Befehl auszuführen, als eine Anmeldeumgebung zu erhalten. Angesichts dessen scheint es, dass die Leute, die OpenSSH geschrieben haben, beschlossen haben, es wie diese Art von 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 würden jedoch nicht-interaktive Shells ~/.bashrc
nicht automatisch ausgeben was hier eindeutig passiert. bash
versucht uns hier wirklich zu helfen. Aus der Dokumentation
Wird von einem entfernten Shell-Daemon aufgerufen
Bash versucht festzustellen, wann es mit seiner Standardeingabe ausgeführt wird, die mit einer Netzwerkverbindung verbunden ist, wie wenn es vom Remote-Shell-Daemon, normalerweise rshd, oder dem Secure-Shell-Daemon sshd ausgeführt wird. Wenn Bash feststellt, dass es auf diese Weise ausgeführt wird, liest und führt es Befehle aus ~/.bashrc aus, wenn diese Datei existiert und lesbar ist. Es wird dies nicht tun, wenn es als sh aufgerufen wird. Die Option --norc kann verwendet werden, um dieses Verhalten zu verhindern, und die Option --rcfile kann verwendet werden, um das Lesen einer anderen Datei zu erzwingen, aber weder rshd noch sshd rufen im Allgemeinen die Shell mit diesen Optionen auf oder lassen zu, dass sie angegeben werden.
Das warum dieses Verhaltens liegt auf einer niedrigeren Ebene als Shells:ssh host
(der "Login-Shell"-Fall) verwendet ein Pseudoterminal auf dem entfernten Host, um zwischen sshd
zu kommunizieren Serverprozess und die Shell; ssh host command
verwendet Pipes zwischen sshd
und command
, stattdessen. 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 zu löschen. Aber sie haben mehr Overhead und erlauben (abhängig von der Konfiguration) nicht, dass beliebige Daten unverändert durchgelassen werden, sodass SSH ihre Verwendung vermeidet, wenn keine Interaktion stattfindet.
Manchmal misslingt die SSH-Befehl/Kein-Befehl-Heuristik dies; es kann mit dem -t
überschrieben werden und -T
Schalter. Zum Beispiel, um sich bei einem Remote-Rechner anzumelden und einen angehaltenen screen
sofort wieder anzuhängen Sitzung müssen Sie ssh -t host screen -R
ausführen; ssh host screen -R
wird screen
verursachen sich darüber beschweren, nicht mit einem Terminal verbunden zu sein. Ich kann mir keine Situation vorstellen, in der Sie tatsächlich wollen würden um -T
zu verwenden , aber es ist da, falls du jemals eins findest.