SSH 转义键(“~”)仅在连接卡住时有效?

Ale*_*x D 14 ssh openssh

当我的 SSH 连接没有响应时,我可以使用<enter>~.. 但是,当连接响应时,~转义不起作用。它只是在控制台打印一个 tilda。

因此,如果我想修改 SSH 端口转发并按<enter>~C<enter>,我得到的只是:

~C: command not found

(来自bash,不是来自ssh。)

我需要做什么才能使 SSH 转义密钥正常工作?

编辑:我发现了一个很大的线索:远程外壳实际上是ash,而不是bash。当我bash在远程机器上运行时,SSH 转义键起作用了!当我再次ashbashinside 中运行ash时,它不起作用!

但这很奇怪。转义密钥应该被 SSH 客户端捕获,甚至不会转发到远程 shell。那么,为什么哪个远程 shell 正在接收来自 SSH 的输入呢?

小智 11

简单的解决方法:运行cat命令,然后输入转义序列。

cat命令默认会打印传入的内容stdin,因此在它运行时不会发送任何转义字符,您可以正常使用 ssh 转义键。如果做到了这ctrl-ccat回外壳。

示例 如果需要,打开一个提示并cat通过键入cat并按 Enter来执行。

$ 
$ cat 
Run Code Online (Sandbox Code Playgroud)

现在输入~?

~?
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
Run Code Online (Sandbox Code Playgroud)

有用!现在只需输入任何命令。然后返回提示按 control-C。

^C
$
Run Code Online (Sandbox Code Playgroud)


Ale*_*x D 7

我发现了秘密!

正如我在上面的“编辑”中发布的那样,远程 shell 是 BusyBox ash,而不是bash.

来自libbb/lineedit.c:2336-2338, 在 BusyBox 源中:

/* Print out the command prompt, optionally ask where cursor is */
parse_and_put_prompt(prompt);
ask_terminal();
Run Code Online (Sandbox Code Playgroud)

用于在ash. 但是请注意,一旦打印提示,ask_terminal就会调用另一个调用的函数。有什么作用ask_terminal?它打印出以下字符:<ESCAPE>[6n.

您永远不会在终端中看到这些字符。实际上,它们是 ANSI 终端控制转义码。<ESC>[6n是一个“查询光标位置”命令——它告诉终端模拟器发回另一个 ANSI 转义码,它告诉外壳光标(文本插入点)在终端窗口中的位置。

因此,只要您按下Enter,就会ash打印出<ESC>[6nsshd并将其ssh从那里传回并从那里传回终端仿真器。在您按下 之前~,您的终端模拟器立即向<ESC>[47;13R标准输入发送类似内容,并ssh通过连接将其传递给sshd和从那里传递到ash,告诉ash您光标的位置。

现在,SSH 客户端实际上并不知道那些 ANSI 转义码的含义。对于 SSH,它们都只是从标准输入中读取的字符。<ENTER>~CSSH 客户端看到的不是,而是看到<ENTER><ESC>[47;13R~C,并且由于它没有看到~右后的Enter,因此它不认为它是转义码。

问题是如何处理这个问题。如果 OpenSSH 能够理解终端发送的那些 ANSI 转义~符并且在 ANSI 终端控制命令之后仍然接受转义符,那就太好了。我可能会向 OpenSSH 人员发送一个补丁,看看他们是否有兴趣解决这个问题...

  • 顺便说一句,我向 OpenSSL 开发人员发送了一个补丁来修复这个问题......但它悬而未决,没有被拒绝,但也没有合并。 (2认同)