%20funktioniert%20nur%2C%20wenn%20die%20Verbindung%20h%C3%A4ngt%3F.png)
Wenn meine SSH-Verbindung nicht reagiert, kann ich sie mit beenden <enter>~.
. Wenn die Verbindung jedoch reagiert, ~
funktioniert das Escape nicht. Es wird nur eine Tilda auf der Konsole ausgegeben.
Wenn ich also die SSH-Portweiterleitung ändern möchte und drücke <enter>~C<enter>
, erhalte ich nur Folgendes:
~C: command not found
(Von bash
, nicht von ssh
.)
Was muss ich tun, damit die SSH-Escape-Taste ordnungsgemäß funktioniert?
BEARBEITEN:Ich habe einen wichtigen Hinweis gefunden: Die Remote-Shell war tatsächlich ash
, nicht bash
. Wenn ich bash
auf dem Remote-Rechner laufe, funktioniert die SSH-Escape-Taste! Wenn ich ash
innerhalb von bash
ausführe ash
, funktioniert es wieder nicht!
Aber das ist sehr seltsam. Die Escape-Taste sollte vom SSH-Client abgefangen und nicht einmal an die Remote-Shell weitergeleitet werden. Warum sollte es also wichtig sein, welche Remote-Shell genau die Eingabe von SSH empfängt?
Antwort1
Einfache Problemumgehung: Führen Sie den cat
Befehl aus und geben Sie dann die Escape-Sequenz ein.
Der cat
Befehl druckt standardmäßig das, was übergeben wird stdin
. Während der Ausführung werden also keine Escape-Zeichen gesendet und Sie können die SSH-Escape-Taste wie gewohnt verwenden. Wenn Sie fertig sind, ctrl-c
kehren Sie einfach cat
zur Shell zurück.
Beispiel
Öffnen Sie bei Bedarf eine Eingabeaufforderung und führen Sie die Ausführung cat
durch Eintippen cat
und Drücken der Eingabetaste aus.
$
$ cat
Geben Sie jetzt ~? ein.
~?
Supported escape sequences:
~. - terminate connection (and any multiplexed sessions)
~B - send a BREAK to the remote system
~C - open a command line
~R - request rekey
~V/v - decrease/increase verbosity (LogLevel)
~^Z - suspend ssh
~# - list forwarded connections
~& - background ssh (when waiting for connections to terminate)
~? - this message
~~ - send the escape character by typing it twice
Es funktioniert! Geben Sie jetzt einfach einen beliebigen Befehl ein. Um zur Eingabeaufforderung zurückzukehren, drücken Sie Strg+C.
^C
$
Antwort2
Ich habe das Geheimnis herausgefunden!
Wie ich oben im „Edit“ geschrieben habe, war die Remote-Shell BusyBox ash
, nicht bash
.
Von libbb/lineedit.c:2336-2338
, in den BusyBox-Quellen:
/* Print out the command prompt, optionally ask where cursor is */
parse_and_put_prompt(prompt);
ask_terminal();
Damit wird die Eingabeaufforderung in ausgedruckt ash
. Beachten Sie jedoch, dass, sobald die Eingabeaufforderung ausgedruckt wird, eine andere Funktion aufgerufen ask_terminal
wird. Was macht ask_terminal
sie? Sie druckt die folgenden Zeichen aus: <ESCAPE>[6n
.
Sie sehen diese Zeichen nie in Ihrem Terminal. Tatsächlich handelt es sich um einen ANSI-Escape-Code für die Terminalsteuerung. <ESC>[6n
ist ein Befehl zum Abfragen der Cursorposition – er weist den Terminalemulator an, einen weiteren ANSI-Escape-Code zurückzusenden, der der Shell mitteilt, wo sich der Cursor (Texteinfügepunkt) im Terminalfenster befindet.
Sobald Sie also drücken Enter
, ash
wird ausgegeben <ESC>[6n
und das Ergebnis an den Terminalemulator und von dort an diesen sshd
weitergeleitet . Unmittelbar bevor Sie drücken können , sendet Ihr Terminalemulator etwas wie an die Standardeingabe und leitet das über die Verbindung an und von dort an weiter , um mitzuteilen, wo sich Ihr Cursor befindet.ssh
~
<ESC>[47;13R
ssh
sshd
ash
ash
Nun weiß der SSH-Client nicht wirklich, was diese ANSI-Escape-Codes bedeuten. Für SSH sind sie alle nur Zeichen, die von der Standardeingabe gelesen werden. Statt zu sehen <ENTER>~C
, sieht der SSH-Client , und da er das direkt danach folgende <ENTER><ESC>[47;13R~C
nicht sieht , denkt er nicht, dass es ein Escape-Code ist.~
Enter
Die Frage ist, was man dagegen tun kann. Es wäre schön, wenn OpenSSH diese vom Terminal gesendeten ANSI-Escapezeichen verstehen und das ~
Escapezeichen nach einem ANSI-Terminalsteuerbefehl weiterhin akzeptieren würde. Vielleicht schicke ich den OpenSSH-Leuten einen Patch und frage, ob sie daran interessiert sind, das Problem zu beheben ...
Antwort3
Du hast gefragtSo sollte die Escape-Taste des SSH-Clients doch sicher nicht funktionieren, oder?
Ja, es sollte so funktionieren:
Wenn Sie Enterdann drücken ~und das Zeichen in der Eingabeaufforderung nicht angezeigt wird, ~
wird das Escape-Zeichen verwendet ssh
.
Wenn Sie erneut drücken, ~wird es in Ihrer Eingabeaufforderung angezeigt und es wird auf die Arbeitsshell (die Bash in Ihrem Beispiel) einwirken, die versuchen wird,expandierenund verwenden, wie es bekannt ist.
Beachten Sie, dass dies ~
die erste IhrerZeilenpuffer, wenn Sie also ein beliebiges Zeichen eingeben und nach dem Löschen der gesamten Zeileneuund Sie müssen Entererneut drücken.
Wenn ich drücke, ~?
erhalte ich
Unterstützte Escape-Sequenzen:
~. – Verbindung beenden (und alle Multiplex-Sitzungen)
~B – ein BREAK an das Remote-System senden
~C – eine Befehlszeile öffnen
~R – erneute Schlüsselerstellung anfordern (nur SSH-Protokoll 2)
~^Z – SSH anhalten
~# – weitergeleitete Verbindungen auflisten
~& – SSH im Hintergrund (beim Warten auf die Beendigung von Verbindungen)
~? – diese Nachricht
~~ – das Escape-Zeichen durch zweimaliges Eintippen senden
(Beachten Sie, dass Escape-Zeichen nur unmittelbar nach einer neuen Zeile erkannt werden.)