Das Problem und seine Lösung

Das Problem und seine Lösung

Ich habe ein seltsames SCP-Problem:

$ scp [email protected]:~/test.txt ./
Password:
\033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H \033H

Das Passwort wird problemlos akzeptiert, aber es kommt dieses komische \033H-Ding. Und die Datei wird nicht übertragen. Hat jemand eine Idee?

Antwort1

Die Lösung hierfür ist normalerweise einfach. Normalerweise können Sie prüfen .bashrc, die Zeile oder die Zeilen oben finden, die das Problem verursachen, und sie verschieben oder löschen. Der schwierige Teil besteht darin, die Leute davon zu überzeugen, dass dieses Problem tatsächlich besteht. Details folgen, aber wenn Sie nurFixdieses Problem, dann müssen Sie nur diesen kürzeren ersten Abschnitt verwenden.

Das Problem und seine Lösung

Dies geschieht, wenn .bashrcdas Home-Verzeichnis des Benutzers auf dem Remote-Computer Befehle enthält, die eine Ausgabe erzeugenund die auch in nicht interaktiven Shells laufen.In selteneren Fällen kommt es auch vor, wenn das System /etc/bash.bashrcsolche Befehle enthält. Die spezifische Ausgabe variiert je nachdem, was sie erzeugt. Aber die Kombination aus unerwarteter Ausgabe undnichtErfolgreiche oder überhaupt gestartete Überweisungensehrdeutet stark auf diese Ursache hin (insbesondere, wenn der Server ein Debian- oder Ubuntu-System ist). scpverwendetStandardeingabe und -ausgabezum Senden und Empfangen von Daten. Wenn über sie nicht zugehörige Daten übertragen werden, können keine Dateien übertragen werden.

Wenn Sie denken,„Das geht nicht, .bashrcist nur für interaktive Shells!“oder aus anderen Gründen an einer detaillierten Erklärung interessiert sind, warum dies geschieht, siehe den zweiten Abschnitt weiter unten.

Dieses Problem unterbricht normales SSHing nicht. Vorausgesetzt, das System ist so konfiguriert, dass Sie sich ssherfolgreich bei einer interaktiven Login-Shell anmelden können, können Sie dies tun, .bashrcdas Home-Verzeichnis des Remote-Benutzers öffnen und #den oder die fehlerhaften Befehle entweder entfernen oder (mit ) auskommentieren, wenn Sie sie nicht benötigen. Oder wenn Sie sie benötigen, verschieben Sie sie unter einen anderen Befehl, der abgebrochen wird, wenn die Shell nicht interaktiv ist. Ein solcher Befehl ist möglicherweise bereits vorhanden.In Ubuntu und einigen anderen Distributionen beginnen Benutzerdateien .bashrcund das gesamte System /etc/bash.bashrcnormalerweise mit solchen Überprüfungen.

Die Standarddatei .bashrcin Ubuntu, die /etc/skelbeim Erstellen eines Benutzerkontos kopiert wird, enthält diesen Code, um zu überprüfen, ob die laufende Shell interaktiv ist, und um zu verhindern, dass weitere Befehle in der Datei ausgeführt werden, wenn dies der Fall ist.nicht:

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

Eine weitere gängige Methode, die manche Leute in ihren .bashrcDateien verwenden und die derzeit in der systemweiten Datei für alle Benutzer verwendet wird /etc/bash.bashrc, ist:

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

Wenn die Dateien ersetzt oder gegenüber der Standardeinstellung geändert wurden, können Sie in beiden Dateien die Verwendung einer der beiden Techniken sehen. Es gibt andere Möglichkeiten, um auf interaktive Vorgänge zu prüfen, aber diese sind selten. Wenn der Benutzer seine eigene .bashrcDatei von Grund auf neu geschrieben oder sie von einem anderen Betriebssystem als Debian, Ubuntu oder einem anderen Debian-Derivat übernommen hat, ist es wahrscheinlich, dass er überhaupt keinen solchen Code hat. Aber wenn Sie ihn brauchen, können Sie ihn trotzdem hinzufügen.

Jeder Befehl, der eine Ausgabe erzeugt und in .bashrcoder erscheint /etc/bash.bashrc, es sei denn, er erscheintnachCode wie der oben gezeigte führt dazu, dass zu Beginn einer Sitzung unerwartete Daten gesendet werden scpund keine scpDateien übertragen werden können.

Wenn Sie kürzlich eine dieser Dateien selbst bearbeitet haben, indem Sie oben einen Befehl hinzugefügt haben, sollte es für Sie einfach sein, die spezifische Änderung herauszufinden, die das Problem verursacht hat. Selbst wenn nicht, könnte die obige Beschreibung Ihnen ausreichende Informationen liefern.

Ich empfehle Ihnen jedoch, Ihre Frage mit allen Einzelheiten zu bearbeiten, einschließlich des Inhalts dieser Dateien, unabhängig davon, ob Sie das Problem anhand der obigen Erklärung lösen können oder nicht. Denken Sie daran, dassDabei handelt es sich um die Dateien auf dem Remote-Server und nicht auf dem Client-Rechner.. Dies sollte anderen, die Ihre Frage finden, dabei helfen, das Problem zu verstehen. Außerdem ermöglicht es, bei Bedarf spezifischere Ratschläge zu geben.

Ich halte die Wahrscheinlichkeit, dass Ihr Problem eine ganz andere Ursache hat, für sehr gering, aber in jedem Fall sollten die zusätzlichen Informationen eine Gewissheit ermöglichen.Andere Leuteals der Autor dieser Frage, die ähnliche Probleme haben und Hilfe bei der Lösung benötigen, sollten natürlichnichtdiese Frage bearbeiten, aber eine eigene Frage posten.


Warum das Problem auftritt

Es wird oft behauptet, dass dies .bashrcnur für interaktive Shells gilt, aber das ist ein Missverständnis oder bestenfalls eine starke Vereinfachung. bashführt Befehle aus von ~/.bashrcund /etc/bash.basrhcwann:

  1. die Shell ist interaktiv,oder
  2. ein anderes Startskript wie /etc/profileoder~/.profile Quellen es,aber auch
  3. when bashwird weder interaktiv noch als Login-Shell ausgeführt, stellt aber fest, dass es wahrscheinlich als initiale Shell ausgeführt wirdin einer Remote-Verbindung.

Was bashals ausreichenden Beweis dafür ansieht, dass es sich um eine Remote Shell handelt - und ob dieser Effekt in der Praxis bei SSH überhaupt auftritt - hängt hauptsächlich davon ab,wie es kompiliert wurde, was je nach Betriebssystem unterschiedlich istund zweitens von der Version von bashunddie Version vonsshddas wird verwendet.

Auf aktuellen Debian- und Ubuntu-Systemen bashwird bei der Ausführung als nicht interaktive Shell ohne Login geprüft, ob die SSH_CLIENTUmgebungsvariable gesetzt und nicht leer ist. (Es werden auch andere Dinge geprüft, aber für SSH auf aktuellen Ubuntu-Systemen wird nichts angezeigt.) Wenn dies der Fall ist und die SHLVLUmgebungsvariable auf einen Wert kleiner als 2 gesetzt ist, was darauf hinweist, dass es sich um die Sitzung handeltanfänglichShell – bashführt die Befehle in /etc/bash.bashrcund aus ~/.bashrc.

Um dies schnell zu überprüfen, ohne Konfigurationsdateien zu ändern, können LeserÜbergeben Sie diese Variablen manuell an bash -c ''die Umgebung von und verfolgen Sie, was sie liestoder untersuchen Sie die run_startup_filesFunktion inshell.c(die in dieser Version in Zeile 1022 beginnt).

Eine nicht interaktive bashShell ohne Anmeldung erhalten Sie, wenn Sie ein Skript mit ausführen bash, entweder indem Sie es ausführen, nachdem Sie die erforderlichen Berechtigungen festgelegt und ihmeine passende Hashbang-Zeileoder durch explizites Ausführen. Es ist auch das, was Sie erhalten, wenn Sie einen Einzeiler mit der Option ausführen, wie zum Beispiel:bash your-scriptbash-c

bash -c 'echo hello world'

Wie zu erwarten, die Shell, die Sie erhalten, wenn SieAnmeldungüber SSH für eineinteraktive Sitzungist eine interaktive Login-Shell. Das ist, was Sie erhalten, wenn Sie einen Befehl wie diesen ausführen (vorausgesetzt, er ist erfolgreich):

ssh [email protected]

Aber hier kommt der nicht-intuitive Teil ins Spiel: die Shell, die Sie erhalten, wenn SieAnmeldungüber SSH für einenicht interaktivSitzung ist eine nicht interaktiveNicht-LoginShell. Das erhalten Sie, wenn Sie einen einzigen Befehl über SSH ausführen:

ssh [email protected] command args...

Das bedeutet, dass das Ausführen eines einzelnen Befehls über SSH bashals dieselbe Art von Shell ausgeführt wird – eine nicht interaktive Shell ohne Anmeldung –, als wenn Sie einen einzelnen Befehl lokal (oder innerhalb einer bereits eingerichteten Remote-Sitzung) mit ausführen bash -c.

Wie sshim Allgemeinen scpbewirkt , dass auf dem Remote-Rechner eine Shell als Remote-Benutzer ausgeführt wird. Dies ist immer noch die Shell, die der Benutzer als solche konfiguriert hat, d. h. die Shell, die im Eintrag des Benutzers in /etc/passwdoder in der Ausgabe von aufgeführt ist getent passwd(die auch als Wert der $SHELLUmgebungsvariable festgelegt wird, wenn er angemeldet ist). Sofern der Benutzer sie nicht durch Ausführen geändert hat chsh, ist dies die Standardbenutzer-Shell, die in Ubuntu lautet bash.

Deshalb Befehle wieDasbashFühren Sie auch auf dem Remote-Server eine nicht interaktive Shell ohne Anmeldung aus :

scp [email protected]:~/test.txt ./

Sofern sie nicht durch Code geschützt sind, der sie stoppt, wenn die Shell nicht interaktiv ist, werden Befehle in einer solchen Shell ausgeführt .bashrcoder /etc/bash.bashrcvon ihr ausgeführt. Wenn sie eine Ausgabe erzeugen – absichtlich oder unabsichtlich – dannscpkann keine Dateien kopieren.

verwandte Informationen