问题描述
所以我在服务器上运行 apt-get upgrade
时,路由器认为它自上次让我生气的时间太长了:它断开了所有连接。这个故事的寓意是当你在一个流浪的路由器上时经常使用 screen
。
无论如何,我重新登录并在 htop 中发现该进程仍然挂在那里,仍在等待我的 Y/n 升级(还没有命中,幸运的是)。有什么方法可以重新连接到已中断的会话?我最终只是杀死了它,因为它不在包管理的中间,但很高兴知道以供将来参考。
最佳方法
虽然您无法重新连接到损坏的 SSH 会话,但您可以重新设置在 SSH 中运行的进程的父级 – 在功能上与您想要的相同。
Instructions
在您的情况下,您将接管 apt-get
进程以从新的 SSH 会话、screen
会话等进行控制。我最喜欢的是 reptyr
命令:
$ sudo apt-get install reptyr
$ ps ax | grep apt-get
10626 pts/8 R+ 0:32 apt-get upgrade
然后,使用您为您的流程找到的 pid:
$ sudo reptyr -T 10626
或者,如果这不起作用,请尝试:
$ reptyr 10626
在此阶段之后,您的所有键盘输入都会进入您接管的程序。不幸的是,您不会看到 SSH 会话的旧输出,例如要求您确认的 apt-get
输出。
解释
还有多种其他工具的工作原理与 reptyr
基本相同(即通过 ptrace
调试附件)。请参阅以下讨论它们的问题和答案:
在上面的说明中,reptyr 10626
使用 ptrace
调试附件,而 sudo reptyr -T 10626
命令使用 TTY 窃取,更可取( details )。
最后,你不能以这种方式接管 SSH 会话的原因是因为 sshd
进程不受主机终端控制,而是提供终端的从属部分——pts
设备——而主控部分驻留在客户端机器上,这里有一个 broken-down SSH 会话。当您使用 reptyr -s <pid>
强制接管这样的 sshd
进程时,您的键盘输入将转到该进程,而不是其活动子进程。所以 “Ctrl+Z” 只会杀死 sshd
。
次佳方法
正确问题的答案是:你不能。我认为主要问题是身份验证程序将不同步。它只是不那样工作。
正如您自己所注意到的,解决方案是尽可能使用 screen(顺便说一下,tmux 是 screen 的替代方案)。
第三种方法
为了运行持久的进程,如果你想要一个更友好的界面,我使用 screen 或 byobu。
对于屏幕,您可以使用:
screen [program] [args]
这将在屏幕会话中运行 [program] 及其 [args]。程序完成后,会话将自动关闭。如果您希望在程序运行后保留会话,只需运行 screen 而不带任何参数,会话中将出现一个新提示。 CTRL+A+D 将终端与当前会话分离。
到 re-attach 到上一个会话:
screen -r
如果只有一个会话打开,它将立即重新连接。如果正在进行多个会话,它会询问您要附加到哪个会话。如果您知道会话名称,则只需将其作为参数添加到此命令行即可。
Byobu 是一个不错的改进。它基于屏幕,但在底部提供了一个栏,将所有当前会话显示为选项卡,并提供更简单的快捷方式来移动这些会话。你可以:
-
F2 开始一个新的会话
-
F3 移动到左侧的下一个会话选项卡
-
F4 移到右侧的下一个会话选项卡
-
F8 为当前会话选项卡提供友好名称
-
F9 打开选项菜单
-
CTRL+A+D 将所有会话与终端分离。
忠告:避免使用 root 用户打开会话。如果有人获得对您终端的访问权限(本地或远程),他们可以轻松地通过 re-attach 进入正在进行的会话并以 root 用户身份使用您的系统。如果需要,最好根据需要使用公共用户和 sudo 个人命令行启动会话。