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 .bashrc
das 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.bashrc
solche 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). scp
verwendetStandardeingabe 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, .bashrc
ist 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 ssh
erfolgreich bei einer interaktiven Login-Shell anmelden können, können Sie dies tun, .bashrc
das 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 .bashrc
und das gesamte System /etc/bash.bashrc
normalerweise mit solchen Überprüfungen.
Die Standarddatei .bashrc
in Ubuntu, die /etc/skel
beim 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 .bashrc
Dateien 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 .bashrc
Datei 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 .bashrc
oder 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 scp
und keine scp
Dateien ü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 .bashrc
nur für interaktive Shells gilt, aber das ist ein Missverständnis oder bestenfalls eine starke Vereinfachung. bash
führt Befehle aus von ~/.bashrc
und /etc/bash.basrhc
wann:
- die Shell ist interaktiv,oder
- ein anderes Startskript wie
/etc/profile
oder~/.profile
Quellen es,aber auch - when
bash
wird weder interaktiv noch als Login-Shell ausgeführt, stellt aber fest, dass es wahrscheinlich als initiale Shell ausgeführt wirdin einer Remote-Verbindung.
Was bash
als 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 bash
unddie Version vonsshd
das wird verwendet.
Auf aktuellen Debian- und Ubuntu-Systemen bash
wird bei der Ausführung als nicht interaktive Shell ohne Login geprüft, ob die SSH_CLIENT
Umgebungsvariable 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 SHLVL
Umgebungsvariable auf einen Wert kleiner als 2 gesetzt ist, was darauf hinweist, dass es sich um die Sitzung handeltanfänglichShell – bash
führt die Befehle in /etc/bash.bashrc
und 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_files
Funktion inshell.c
(die in dieser Version in Zeile 1022 beginnt).
Eine nicht interaktive bash
Shell 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-script
bash
-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 bash
als 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 ssh
im Allgemeinen scp
bewirkt , 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/passwd
oder in der Ausgabe von aufgeführt ist getent passwd
(die auch als Wert der $SHELL
Umgebungsvariable 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 wieDasbash
Fü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 .bashrc
oder /etc/bash.bashrc
von ihr ausgeführt. Wenn sie eine Ausgabe erzeugen – absichtlich oder unabsichtlich – dannscp
kann keine Dateien kopieren.