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

cof*_*Mug 20 ssh remote

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

Gil*_*il' 22

该命令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 &'
Run Code Online (Sandbox Code Playgroud)

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

  • 如果有人正在寻找一种从远程主机内执行此操作的方法(类似的解决方案):`(sleep 1 && sudo reboot &) && exit`。括号产生一个子进程,它等待一秒钟,然后启动重新启动。然而,主机进程会立即终止 ssh 会话。我不是 shell 专家,但到目前为止这对我有用。 (3认同)

Rom*_*jev 11

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

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

$ ssh -o "ServerAliveInterval 2" root@remotehost reboot
Run Code Online (Sandbox Code Playgroud)

所述选项使客户端每 2 秒通过安全通道戳服务器。最终随着重新启动的进行,它将停止响应并且客户端将断开连接。


小智 7

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

ssh user@192.168.0.130 "nohup sudo reboot &>/dev/null & exit"
Run Code Online (Sandbox Code Playgroud)

解释:

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

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