A chave de escape SSH (“~”) só funciona quando a conexão está travada?

5

Quando eu tenho uma conexão SSH sem resposta, posso matá-lo com <enter>~. . No entanto, quando a conexão está respondendo, o escape ~ não funciona. Apenas imprime um tilda no console.

Então, se eu quiser modificar o encaminhamento de porta SSH e pressionar <enter>~C<enter> , tudo que eu obtenho é:

~C: command not found

(De bash , não de ssh .)

O que preciso fazer para que a chave de escape do SSH funcione corretamente?

EDIT: Encontrei uma grande pista: o shell remoto era na verdade ash , não bash . Quando eu executo bash na máquina remota, a chave de escape SSH funciona! Quando eu executo ash dentro de bash dentro de ash , novamente, não funciona!

Mas isso é muito estranho. A chave de escape deve ser capturada pelo cliente SSH e nem mesmo encaminhada para o shell remoto. Então, por que deveria importar exatamente qual shell remoto está recebendo entrada do SSH?

    
por Alex D 12.10.2015 / 10:19

3 respostas

3

Solução alternativa simples: execute o comando cat e, em seguida, insira a sequência de escape.

O comando cat por padrão imprime o que é passado em stdin , então, enquanto estiver rodando, não haverá caracteres de escape enviados e você poderá usar a chave de escape ssh normalmente. Quando feito, basta ctrl-c de cat voltar para o shell.

Exemplo Se necessário, abra um prompt e execute cat digitando cat e pressionando Enter.

$ 
$ cat 

Agora digite ~?

~?
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! Agora basta digitar qualquer comando. Então, para retornar ao prompt pressione Ctrl-C.

^C
$
    
por 27.03.2017 / 20:36
2

Eu descobri o segredo!

Como postei na "edição" acima, o shell remoto era BusyBox ash , não bash .

De libbb/lineedit.c:2336-2338 , nas fontes do BusyBox:

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

Isso é usado para imprimir o prompt de comando em ash . Mas note, assim que imprimir o prompt, outra função chamada ask_terminal é chamada. O que ask_terminal faz? Imprime os seguintes caracteres: <ESCAPE>[6n .

Você nunca vê esses caracteres no seu terminal. Na verdade, eles são um código de escape de controle de terminal ANSI. <ESC>[6n é um comando "Query Cursor Position" - diz ao emulador de terminal para enviar outro código de escape ANSI, que informa ao shell onde o cursor (ponto de inserção de texto) está localizado na janela do terminal.

Assim, quando você pressionar Enter , ash imprimirá <ESC>[6n e sshd passará de volta para ssh e, a partir daí, para o emulador de terminal. Imediatamente, antes que você possa pressionar ~ , seu emulador de terminal enviará algo como <ESC>[47;13R para a entrada padrão e ssh transmitirá a conexão para sshd e daí para ash , informando ash onde seu cursor é.

Agora, o cliente SSH não sabe realmente o que significam esses códigos de escape ANSI. Para SSH, eles são todos apenas caracteres lidos a partir da entrada padrão. Em vez de ver <ENTER>~C , o cliente SSH vê <ENTER><ESC>[47;13R~C e, como não vê o ~ logo após Enter , não acha que seja um código de escape.

A questão é o que fazer sobre isso. Seria bom se o OpenSSH entendesse os escapes ANSI enviados pelo terminal e ainda aceitaria o caractere de escape ~ após um comando de controle do terminal ANSI. Eu posso enviar um patch para os caras do OpenSSH e ver se eles estão interessados em consertar isso ...

    
por 12.10.2015 / 16:55
0

Você perguntou Certamente, a chave de escape do cliente SSH não deveria funcionar assim ??

Sim, deve funcionar assim:

Se você pressionar Enter então ~ e não aparecerá o caractere ~ no prompt que a fuga estará atuando no ssh .

Se você pressionar novamente ~ , ele aparecerá no seu prompt e ele atuará no shell de trabalho (o bash em seu exemplo), que tentará expandir e usar como ele sabe.

Note que para trabalhar o ~ tem que ser o primeiro do seu buffer de linha , então se você digitar qualquer caractere e depois você apagar toda a linha não é mais novo e você precisa pressionar Enter novamente.

Quando eu pressiono ~? obtenho

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 (SSH protocol 2 only)
~^Z - suspend ssh
~# - list forwarded connections
~& - background ssh (when waiting for connections to terminate)
~? - this message
~~ - send the escape character by typing it twice
(Note that escapes are only recognized immediately after newline.)

    
por 12.10.2015 / 10:36

Tags