![管道断裂后如何重新连接到 ssh 会话?](https://linux22.com/image/824387/%E7%AE%A1%E9%81%93%E6%96%AD%E8%A3%82%E5%90%8E%E5%A6%82%E4%BD%95%E9%87%8D%E6%96%B0%E8%BF%9E%E6%8E%A5%E5%88%B0%20ssh%20%E4%BC%9A%E8%AF%9D%EF%BC%9F.png)
当时我正在服务器上运行apt-get upgrade
,路由器认为距离上次让我生气已经过去太久了:它断开了所有连接。这个故事的寓意是,screen
当你使用一个糟糕的路由器时,要多加利用。
无论如何,我重新登录并在 htop 中发现该进程仍挂在那里,仍在等待我的 Y/n 升级(幸运的是,还没有达到它)。有什么方法可以重新连接到已中断的会话吗?我最终只是将其杀死,因为它不在包管理的中间,但如果能知道以供将来参考,那就太好了。
答案1
虽然你无法重新连接到中断的 SSH 会话,你可以重新设置 SSH 中运行的进程– 功能上等同于您想要的。
指示
在你的情况下,你将接管这个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窃取并且是可取的(细节)。
最后,您无法通过这种方式接管 SSH 会话的原因是,进程sshd
不受主机终端控制,而是提供终端的从属部分(pts
设备)位于客户端计算机上,而控制它的主控部分位于客户端计算机上,两者之间有一个中断的 SSH 会话。当您使用 强制接管此类进程时sshd
,reptyr -s <pid>
您的键盘输入将转到该进程,而不是其活动的子进程。因此,“Ctrl+Z”只会终止该sshd
。
答案2
对你的问题的正确答案是:你不能。我认为主要问题是身份验证程序不同步。它根本行不通。
正如你自己注意到的,解决方案是在可能的情况下使用屏幕(顺便说一下,tmux是屏幕的替代品)。
答案3
对于运行长时间的进程,我使用屏幕, 或者屏风如果您想要更友好的界面。
对于屏幕,您可以使用:
screen [program] [args]
这将在屏幕会话。程序完成后,会话将自动关闭。如果您希望在程序运行后保留会话,只需运行屏幕不带任何参数,会话中会出现一个新提示。Ctrl+A+D将终端与当前会话分离。
要重新连接到上一个会话:
screen -r
如果只打开一个会话,它会立即重新连接。如果正在进行多个会话,它会询问您要连接到哪一个。如果您知道会话名称,您可以将其作为参数添加到此命令行。
屏风是一个很好的改进。它基于屏幕,但在底部提供了一个栏,以选项卡形式显示所有当前会话,并提供更方便的快捷方式来移动这些会话。您可以:
- F2 开始新会话
- F3 移动到左侧的下一个会话选项卡
- F4 移动到右侧的下一个会话选项卡
- F8 为当前会话选项卡指定一个友好名称
- F9 打开选项菜单
- CTRL+A+D 从终端分离所有会话。
忠告:避免离开与用户打开的会话根。如果任何人获得对您的终端的访问权限(本地或远程),他们可以轻松重新连接到正在进行的会话并以 root 身份使用您的系统。如果需要,最好使用普通用户启动会话,然后须藤根据需要指定单独的命令行。
答案4
do-dist-upgrade
我通过 ssh 从一台进入挂起状态的笔记本电脑上执行操作,因此Broken pipe
。回到机器后,我看到与升级相关的进程仍在运行,其中包括要求whiptail
我输入(选择哪个显示管理器)以及相关的 root 拥有的SCREEN
。我能够执行sudo su -
并附screen -r
加到会话,瞧,我面前的鞭尾对话框能够接受输入。我能够无缝恢复升级。
注意:这是从 Ubuntu 14.04 到 16.04 的升级。