阅读这个问题让我开始疑惑。假设screen
没有被使用。如果 Linux 目标上的 SSH 会话因某种原因被中断,并且您在服务器因超时而终止会话之前重新连接,是否有可能重新获得对正在运行的命令的控制权,以便它不会因为会话中断而被中止?
答案1
尝试将新终端的当前 STD* 文件描述符连接到旧的正在运行的进程只会带来麻烦。即使您设法做到这一点,终端的作业控制也不会按预期工作。如果您最终退出被接管的程序,您将留下一片混乱,而牺牲其文件描述符以交给新后台进程的 shell 会发生什么。当该 shell 消失时,ssh 会保持打开状态吗?可能不会。所以您需要先将其重定向到其他地方。
不管是否可能,我敢打赌,让被遗弃的进程“自然”地被杀死是更可取的。如果你正在做一件足够重要的事情,值得尝试做所有必要的黑客行为来恢复控制和您处于一个不稳定的链接上,您应该提前知道这一点,然后使用屏幕(或 vnc,或任何能让您的独立控制船浮动的东西)。:)
答案2
我知道这是一个老问题,但我觉得有必要添加我的发现,以防其他人像我一样遇到这个问题。
是的,我还没有看到这样做有什么不寻常的后果,但这是我用过的方法,效果非常好。有时当我们在服务器上运行长时间的进程时,它会偶尔断开 ssh 会话。该进程和 tty 会话似乎仍在运行,但我们无法重新连接到它。我找到了下面的程序来将进程拉到新连接的会话中。
https://github.com/nelhage/reptyr
更多信息
答案3
通常,处理此问题的正确方法是提前做好准备,使用 GNUscreen
或 bash 的nohup
或disown
机制。如果您使用的是tcsh
,shell 会在异常退出时放弃后台作业。
如果你没有使用,screen
但设法通过以下方式之一保持进程运行否认方法,你可以假装重新连接到该进程gdb
(来源):
[...] 利用一些肮脏的黑客手段,重新打开一个进程的 stdout/stderr/stdin 并非不可能。[...]
然后使用 gdb 例如附加到进程,做一些调用 close(0)
调用 close(1)
调用 close(2)
调用 open(“/dev/pts/xx”, ...)
调用 dup(0)
调用 dup(0)
分离
现在,你必须根据自己的情况调整这个过程。如果你还没有做到,我怀疑这是否有用否认流程。如果您正在使用bash
,参见此帖关于制作狂欢自动地否认退出时关闭后台进程(基本上就是关闭舒巴坦和购物)。对于前台进程,您需要使用禁止。
答案4
雷蒂也许可以帮助您,但免责声明非常真实且相关:)