为什么需要几十秒才能获得 shell 提示符?

为什么需要几十秒才能获得 shell 提示符?

这是一种常见现象,在通过 SSH 连接到服务器(甚至在我的 Mac 上打开终端)后,登录横幅会立即打印出来,但 shell 提示符需要大约 10 秒到 1 分钟才会出现。此后,性能很好,网络延迟并不罕见。

这似乎不是一个计算困难、内存密集或 IO 密集的任务。它用这数十亿个 CPU 周期来做什么?

答案1

这里可能发生了很多事情。您可以在 shell 手册中找到大多数答案,但这些答案通常非常长且晦涩难懂,因此...

您的问题很可能归结为以下几件事之一。

如果您的配置文件或 bashrc 包含昂贵的东西,请考虑修剪它们。

如果您的配置文件或 bashrc 使用反向 DNS 查找(来设置提示或其他内容),请修复 DNS 或使用主机名。

Shell 在初始化时会打开很多文件,以及其他内容。如果系统负载很高,通常会在此处显示。

如果横幅是预认证,那么它实际上也可能是速度很慢的认证(pam、LDAP 等)。

但也可能不是这些。在显示提示之前发生了许多令人惊讶的事情!

答案2

它可能正在等待 DNS 或尝试通过 LDAP 或类似方式进行身份验证。

尝试添加UseDNS no到 /etc/ssh/sshd_config

如果在本地登录时也发生此情况,请检查您配置的任何 LDAP 服务器或 DNS 服务器是否运行缓慢或无响应。

答案3

一种可能性(其他答案已涉及)是设置 SSH 会话本身的过程就是时间浪费的地方。

另一种可能是,在建立 SSH 会话后,在远程计算机上运行的 shell 启动脚本需要花费很长时间(可能是尝试访问某个损坏的网络挂载)。您可以按如下方式调试第二种可能性:

暂时将以下内容添加到您的顶部~/.bash_profile

set -x
PS4='+ $(date "+%s.%N")\011 '

set -x为每个执行的 shell 命令启用一些调试。变量PS4控制调试的呈现方式 - 具体来说,在这种情况下,我们使用它date来添加时间戳。

然后,您可以分析调试输出的时间戳,查看启动脚本中的哪些命令运行时间过长。

答案4

这是在多数情况下DNS 请求超时。

原因:服务器尝试使用客户端的 IP 地址进行反向 DNS 查找,但未收到回复。如果 A 连接到 B,B 会尝试将 A 的 IP 地址转换为名称。

解决方法:将客户端的 IP 地址和名称输入到服务器的 hosts 文件中。

解决方案:让 DNS 服务器知道所有主机。

相关内容