我在许多控制台(Linux、Mac 等)以及许多不同网络中的许多不同机器上都看到过这种情况。我永远无法确定发生这种情况的确切原因:您所要做的就是通过 SSH 登录到机器。如果连接由于某种原因中断(为简单起见,假设网线被拔掉),那么有时控制台会永远挂起 - 有时,它会正常退出到父 shell。
发生这种情况时真的很烦人(例如,您会丢失命令历史记录。)是否有一个秘密的键盘快捷键可以强制退出(Ctrl-C 或 Ctrl-D 不起作用)?而且,在所有实现中出现这种随机“错误”的原因到底是什么?
答案1
有一个“秘密”的键盘快捷键可以强制退出:~) 从冻结的会话中,按顺序按下这些键:Enter~.波浪号(仅在换行符后)被 ssh 客户端识别为转义序列,句点告诉客户端立即终止其业务。
通信问题上的长时间挂起行为不是错误,SSH 会话挂起,希望另一方能够恢复。如果网络中断,有时甚至几天后您都可以恢复 SSH 会话。当然,您可以使用上述序列明确地告诉它放弃并终止。您还可以做各种事情,例如在客户端中设置保持活动超时,这样如果它在一定时间内没有活动链接,它就会自行关闭,但默认行为是尽可能保持连接!
编辑:此中断键的另一个有用的应用是引起本地 ssh 客户端的注意,并将其置于后台,以便返回到您的本地 shell 一分钟 - 比如从历史记录中获取一些内容 - 然后将其置于后台以继续远程工作。Enter~ Ctrl+Z将 ssh 客户端发送到本地 shell 的后台作业队列,然后fg
像往常一样将其取回。
编辑:处理嵌套的 SSH 会话时,您可以添加多个波浪号,以便只退出链中的一个 SSH 会话,但保留其他会话。例如,如果您嵌套在 3 个级别中(即,您从本地->Machine1->Machine2->Machine3 进行 ssh),Enter~.将使您返回到本地会话,Enter~~.将使您留在 Machine1 中,并将Enter~~~.使您留在 Machine2 中。这也适用于其他转义序列,例如将 ssh 会话暂时移至后台。上述方法适用于任何级别的嵌套,只需添加更多波浪号即可。
最后,您可以使用Enter~?打印可用退出命令的帮助菜单。
TL;DR - 支持的转义命令是支持的转义序列:
~. - 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
(Note that escapes are only recognized immediately after newline.)
答案2
SSH 提供了保持活动的功能。将以下内容添加到本地~/.ssh/config
(如果不存在则创建):
ServerAliveInterval 15
ServerAliveCount 3
此设置将建立通过安全隧道每 15 秒发送一次的保持活动信号。连续三次失败后,SSH 客户端将退出。
请注意,在某些系统(包括 macOS 10.14)上,它需要是:
ServerAliveInterval 15
ServerAliveCountMax 3
摘自 ask.ubuntu 上的这个答案:https://askubuntu.com/a/29967/30266
答案3
它挂起是 TCP 的功能,而不是 SSH 的功能。除非 TCP 通知使用该连接的应用程序该连接不再存在,否则应用程序无法知道 TCP 会话/连接已断开。从每个主机的角度来看,TCP 会话仍处于已建立状态,除了 RST 或对 TCP 保持活动数据包缺乏响应(这并未普遍实现)之外,没有什么可以说长时间空闲(没有数据流)会话无效。在我看来,这似乎不是 SSH 中的错误,我期望这种行为。
答案4
就我而言,问题出在 MTU 过大。如果您使用 NAT,您可以在路由器上更改 MTU,但我在服务器上更改 MTU:
sudo /sbin/ifconfig eth0 mtu 1036
sudo /etc/init.d/networking restart
在 Windows 上,您还可以增加此项:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters]
"TcpMaxDataRetransmissions"=dword:00000010