使用 ssh 命令执行重启后关闭连接

使用 ssh 命令执行重启后关闭连接

我正在reboot -f远程使用该命令强制重新启动 Unix 机器。问题是 ssh 连接长时间保持活动状态,我不知道为什么?我想在重新启动机器后立即关闭 ssh 连接并返回到本地 shell。我怎样才能做到这一点?请注意,不带标志的重新启动命令-f不起作用。

答案1

该命令reboot -f永远不会返回(除非您无权重新启动)。在发出该命令时,SSH 客户端正在等待执行某些操作,这可能是:

  • SSH 服务器通知客户端发生了需要注意的事情,例如有一些输出要显示,或者远程命令已完成;
  • 客户端发生的一些事件,例如要中继的信号;
  • 计时器启动,导致客户端发送保活消息(如果服务器没有回复,则关闭连接)。

由于 SSH 服务器进程已死亡,因此 SSH 客户端在计时器启动之前不会死亡。

如果你运行ssh remotehost 'reboot -f >/dev/null &',那么会发生什么:

  1. 远程 shellreboot在后台启动该命令。
  2. 由于服务器端 shell 命令已退出,并且没有进程保持标准输出打开的文件描述符,因此 SSH 服务器会关闭连接。
  3. reboot命令使机器重新启动。

然而,这并不可靠:根据时间安排,步骤 3 可能会在步骤 2 之前发生。添加计时器使得这种情况不太可能发生:

ssh remotehost '{ sleep 1; reboot -f; } >/dev/null &'

为了绝对确保服务器端致力于运行reboot,同时确保在通知客户端它已提交之前它实际上不会重新启动,您需要从服务器到客户端的附加通知。这可以通过 SSH 连接输出,但会变得复杂。

答案2

我发现这个解决方案最适合我。

-o "ServerAliveInterval 2"与您的命令一起使用ssh,如下所示:

$ ssh -o "ServerAliveInterval 2" root@remotehost reboot

该选项使客户端每 2 秒通过安全通道向服务器发起一次。最终,随着重新启动的进行,它将停止响应,客户端将断开连接。

答案3

有些答案很接近,但正确的答案是:

ssh [email protected] "nohup sudo reboot &>/dev/null & exit"

解释:

  • 您希望exit作为最后一个命令,因此最后一个命令的状态为 0(成功)。如果您愿意,可以预先安排睡眠,但这不是必需的
  • 您需要在后台运行reboot,否则服务器将关闭连接并且您将收到错误消息。在大多数系统上它仍然会重新启动,但如果您正在编写脚本,即使命令正确执行,返回状态也将是错误(不是 0)
  • 在后台运行是不够的,因为stdinstdout仍然通过 SSH 连接到虚拟终端,因此连接不会被关闭。您需要做两件事才能结束 SSH 会话并让命令在后台运行。
    • 1) 您需要重定向stdoutstderrto /dev/null,以便它们不会被保存 SSH 会话的虚拟终端重定向。这就是这&>/dev/null部分。
    • 2)您需要stdin以相同的方式重定向到不可读的文件。这就是 shell 内置函数nohup的作用。

仅在以各种方式与终端分离的后台运行命令时,exit将关闭会话,并且由于虚拟终端上没有stdinstdout留下任何内容,SSH 将终止连接而不会出现错误。

答案4

您是否尝试过以下操作

# shutdown -r now

我发现在我曾经使用过的某些系统上,重新启动命令存在一些问题。然后,我在 shutdown 的联机帮助页中找不到任何与使用 -f 标志重新启动相同的功能。

相关内容