¿La clave de escape SSH ("~") solo funciona cuando la conexión está bloqueada?

¿La clave de escape SSH ("~") solo funciona cuando la conexión está bloqueada?

Cuando tengo una conexión SSH que no responde, puedo eliminarla con <enter>~.. Sin embargo, cuando la conexión responde, el ~escape no funciona. Simplemente imprime una tilda en la consola.

Entonces, si quiero modificar el reenvío del puerto SSH y presiono <enter>~C<enter>, todo lo que obtengo es:

~C: command not found

(De bash, no de ssh.)

¿Qué necesito hacer para que la clave de escape SSH funcione correctamente?

EDITAR:Encontré una gran pista: el shell remoto en realidad ashno era bash. Cuando ejecuto bashen la máquina remota, ¡la clave de escape SSH funciona! Cuando corro ashadentro , nuevamente, bash¡ ashno funciona!

Pero esto es muy extraño. La clave de escape debe ser capturada por el cliente SSH y ni siquiera reenviada al shell remoto. Entonces, ¿por qué debería importar exactamente qué shell remoto recibe información de SSH?

Respuesta1

Solución alternativa simple: ejecute el catcomando y luego ingrese la secuencia de escape.

De forma predeterminada, el catcomando imprimirá lo que se pasa stdin, por lo que mientras se ejecuta no se enviarán caracteres de escape y podrá usar la clave de escape ssh normalmente. Cuando esté listo, ctrl-csalga de catnuevo al caparazón.

Ejemplo Si es necesario, abra un mensaje y ejecútelo catescribiendo caty presionando Intro.

$ 
$ cat 

Ahora escribe ~?

~?
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

¡Funciona! Ahora simplemente ingrese cualquier comando. Luego, para volver al mensaje, presione control-C.

^C
$

Respuesta2

¡He descubierto el secreto!

Como publiqué en la "edición" anterior, el shell remoto era BusyBox ash, no bash.

De libbb/lineedit.c:2336-2338, en las fuentes de BusyBox:

/* Print out the command prompt, optionally ask where cursor is */
parse_and_put_prompt(prompt);
ask_terminal();

Se utiliza para imprimir el símbolo del sistema en formato ash. Pero observe que tan pronto como imprime el mensaje, ask_terminalse llama a otra función. ¿Que es lo que ask_terminalhace? Imprime los siguientes caracteres: <ESCAPE>[6n.

Nunca ves esos caracteres en tu terminal. En realidad, son un código de escape de control de terminal ANSI. <ESC>[6nes un comando de "Consultar posición del cursor": le indica al emulador de terminal que envíe otro código de escape ANSI, que le indica al shell dónde se encuentra el cursor (punto de inserción de texto) en la ventana del terminal.

Entonces, tan pronto como presiona Enter, ashimprime <ESC>[6ny sshdlo pasa de regreso sshal emulador de terminal y desde allí. Inmediatamente, antes de que pueda presionar ~, su emulador de terminal envía algo así como <ESC>[47;13Ra la entrada estándar y sshlo pasa a través de la conexión hacia sshdy desde allí a ash, indicando ashdónde está su cursor.

Ahora, el cliente SSH en realidad no sabe qué significan esos códigos de escape ANSI. Para SSH, todos son solo caracteres leídos de la entrada estándar. En lugar de ver <ENTER>~C, el cliente SSH ve <ENTER><ESC>[47;13R~Cy, dado que no ve el código ~inmediatamente después Enter, no cree que sea un código de escape.

La pregunta es qué hacer al respecto. Sería bueno si OpenSSH entendiera esos escapes ANSI enviados por el terminal y aún aceptara el ~carácter de escape después de un comando de control del terminal ANSI. Puedo enviar un parche a los chicos de OpenSSH y ver si están interesados ​​en solucionar este problema...

Respuesta3

Tu preguntasteSeguramente, ¿se supone que la clave de escape del cliente SSH no funciona así?

Sí, debería funcionar así:

Si presiona Enterentonces ~y no aparecerá el carácter ~en el mensaje de escape se actuará en el archivo ssh.

Si presiona nuevamente, ~aparecerá en su mensaje y actuará en el shell de trabajo (el bash en su ejemplo), que intentaráexpandiry utilizarlo como sabe.

Tenga en cuenta que para trabajar ~tiene que ser el primero de subúfer de línea, por lo que si ingresa cualquier carácter y después de borrar todo, la línea ya no existenuevoy necesitas presionar Enternuevamente.

Cuando presiono ~?obtengo

Secuencias de escape admitidas:
~. - finalizar la conexión (y cualquier sesión multiplexada)
~B - enviar una INTERRUPCIÓN al sistema remoto
~C - abrir una línea de comando
~R - Solicitar una nueva clave (solo protocolo SSH 2)
~^Z - suspender ssh
~# - enumerar las conexiones reenviadas
~ & - ssh en segundo plano (cuando se espera que finalicen las conexiones)
~? - este mensaje
~~ - envíe el carácter de escape escribiéndolo dos veces
(tenga en cuenta que los escapes solo se reconocen inmediatamente después de una nueva línea).

información relacionada