我正在reboot -f
远程使用该命令强制重新启动 Unix 机器。问题是 ssh 连接长时间保持活动状态,我不知道为什么?我想在重新启动机器后立即关闭 ssh 连接并返回到本地 shell。我怎样才能做到这一点?请注意,不带标志的重新启动命令-f
不起作用。
答案1
该命令reboot -f
永远不会返回(除非您无权重新启动)。在发出该命令时,SSH 客户端正在等待执行某些操作,这可能是:
- SSH 服务器通知客户端发生了需要注意的事情,例如有一些输出要显示,或者远程命令已完成;
- 客户端发生的一些事件,例如要中继的信号;
- 计时器启动,导致客户端发送保活消息(如果服务器没有回复,则关闭连接)。
由于 SSH 服务器进程已死亡,因此 SSH 客户端在计时器启动之前不会死亡。
如果你运行ssh remotehost 'reboot -f >/dev/null &'
,那么会发生什么:
- 远程 shell
reboot
在后台启动该命令。 - 由于服务器端 shell 命令已退出,并且没有进程保持标准输出打开的文件描述符,因此 SSH 服务器会关闭连接。
- 该
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)
- 在后台运行是不够的,因为
stdin
和stdout
仍然通过 SSH 连接到虚拟终端,因此连接不会被关闭。您需要做两件事才能结束 SSH 会话并让命令在后台运行。- 1) 您需要重定向
stdout
和stderr
to/dev/null
,以便它们不会被保存 SSH 会话的虚拟终端重定向。这就是这&>/dev/null
部分。 - 2)您需要
stdin
以相同的方式重定向到不可读的文件。这就是 shell 内置函数nohup
的作用。
- 1) 您需要重定向
仅在以各种方式与终端分离的后台运行命令时,exit
将关闭会话,并且由于虚拟终端上没有stdin
或stdout
留下任何内容,SSH 将终止连接而不会出现错误。
答案4
您是否尝试过以下操作
# shutdown -r now
我发现在我曾经使用过的某些系统上,重新启动命令存在一些问题。然后,我在 shutdown 的联机帮助页中找不到任何与使用 -f 标志重新启动相同的功能。