SSH-Escape-Taste („~“) funktioniert nur, wenn die Verbindung hängt?

SSH-Escape-Taste („~“) funktioniert nur, wenn die Verbindung hängt?

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 bashauf dem Remote-Rechner laufe, funktioniert die SSH-Escape-Taste! Wenn ich ashinnerhalb von bashausfü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 catBefehl aus und geben Sie dann die Escape-Sequenz ein.

Der catBefehl 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-ckehren Sie einfach catzur Shell zurück.

Beispiel Öffnen Sie bei Bedarf eine Eingabeaufforderung und führen Sie die Ausführung catdurch Eintippen catund 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_terminalwird. Was macht ask_terminalsie? 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>[6nist 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, ashwird ausgegeben <ESC>[6nund das Ergebnis an den Terminalemulator und von dort an diesen sshdweitergeleitet . 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;13Rsshsshdashash

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~Cnicht 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.)

verwandte Informationen