如何重新连接到分离的 mosh 会话或以其他方式摆脱
Mosh: You have a detached Mosh session on this server (mosh [XXXX]).
即mosh相当于什么
screen -D -R
或者可能
screen -wipe
此外,在文档中哪里可以找到这个答案?
如何重新连接到分离的 mosh 会话或以其他方式摆脱
Mosh: You have a detached Mosh session on this server (mosh [XXXX]).
即mosh相当于什么
screen -D -R
或者可能
screen -wipe
此外,在文档中哪里可以找到这个答案?
出于安全原因,不能重新附加,见https://github.com/keithw/mosh/issues/394
要终止分离的会话,请使用该消息中显示的 PID 号(即“XXXX”部分。)例如,如果您看到 --
Mosh: You have a detached Mosh session on this server (mosh [12345]).
并且可以运行这个命令:
kill 12345
此外,要关闭所有mosh 连接,您可以:
kill `pidof mosh-server`
请注意,如果您当前通过 mosh 连接,则最后一个命令也会断开您的连接。
令我惊讶的是,我使用 CRIU ( https://criu.org ) 来检查点并重新启动 mosh 客户端并且它起作用了。
令人震惊。
找到你的 mosh-client 的 PID:
$ ps -ef | grep 莫什
然后,根据他们的说明安装 CRIU。
然后,像这样检查它:
$ mkdir 检查点
$ sudo ./criu dump -D 检查点 -t PID --shell-job
然后,恢复它:
$ sudo ./criu restore -D 检查点 --shell-job
而且,它就在那里。你的 mosh 客户端回来了。
但是,需要注意的一件事是,如果您的笔记本电脑重新启动(这是我们试图防止的全部问题),mosh 会使用monotonic
时钟来跟踪客户端的时间,这在重新启动后不起作用。但是,如果您的笔记本电脑完全崩溃,这将不起作用,因为 mosh 序列号将与检查点的版本不同步(二进制文件将恢复,但通信将停止)。
为了解决这个问题,您需要告诉 mosh 停止这样做并下载 mosh 源代码。然后,编辑这个文件:
cd mosh
vim 配置文件
然后,搜索GETTIME
并注释掉该行。
然后做:
autoreconf # 或 ./autogen.sh 如果你是第一次克隆它
。/配置
制作
进行安装
之后,您的 CRIU 检查点 mosh 客户端会话将在重新启动后继续存在。
(显然,您需要编写一些内容来定期执行检查点以使其有用。但是,这是对读者的练习)。
我意识到这是一篇旧帖子,但有一个非常简单的解决方案,正如 mosh 作者 Keith Winstein 所建议的那样:https ://github.com/mobile-shell/mosh/issues/394
“嗯,首先,如果你希望能够从多个客户端(或客户端死后)附加到会话,你应该使用 screen 或 tmux。Mosh 是 SSH 的替代品(在某些情况下),而不是 screen。许多 Mosh 用户将它与 screen 一起使用,并喜欢这种方式。”
场景:我通过 mosh 登录到远程服务器。然后,我运行了 screen 并在 screen 会话中运行了一个进程,例如 htop。我失去了连接(笔记本电脑电池没电了,失去了网络连接等)。我通过 mosh 再次连接并在服务器上获取该消息,
Mosh:您在此服务器上有一个分离的 Mosh 会话(mosh [XXXX])。
我所要做的就是杀死之前的 mosh 会话
杀 XXXX
并重新连接到仍然存在的屏幕会话。
屏幕-r
现在,htop(或任何正在运行的进程)恢复原状,没有中断。这对于运行升级或其他进程特别有用,如果突然中断,服务器会处于混乱、未知的状态。我假设你可以用 tmux 做同样的事情,虽然我还没有尝试过。我相信这是 Annihilannic 和 eskhool 所建议的。
作为 Varta 答案的补充,我使用以下命令关闭除当前连接之外的所有 mosh 连接:
pgrep mosh-server | grep -v $(ps -o ppid --no-headers $$) | xargs kill
正如@varta 指出的那样,出于安全原因,mosh 所有者非常反对从不同的客户端重新连接。因此,如果您的客户端消失了(例如,您重新启动了笔记本电脑),您唯一的选择就是终止会话。
要仅终止分离的会话,您可以使用以下行(我在 my 中将其作为别名.bashrc
)。
who | grep -v 'via mosh' | grep -oP '(?<=mosh \[)(\d+)(?=\])' | xargs kill
该命令取决于who
列出已连接用户(包括 mosh 会话)的事实,只有附加的 mosh 会话具有“通过 mosh”,并且 mosh 会话的 pid 位于方括号中。因此,它只为分离的 mosh 会话找到 pid,并使用 xargs 将它们传递给 kill。
这是一个示例who
结果供参考:
$ who
theuser pts/32 2018-01-03 08:39 (17X.XX.248.9 via mosh [193891])
theuser pts/17 2018-01-03 08:31 (17X.XX.248.9 via mosh [187483])
theuser pts/21 2018-01-02 18:52 (mosh [205286])
theuser pts/44 2017-12-21 13:58 (:1001.0)
另一种方法是使用 mosh-server 环境变量MOSH_SERVER_SIGNAL_TMOUT
。您可以.bashrc
在服务器端将其设置为 300 之类的值。然后,如果您执行此操作,pkill -SIGUSER1 mosh-server
它只会杀死在过去 300 秒内未连接的 mosh 服务器(其他服务器将忽略 SIGUSER1)。mosh-server 手册页中的更多信息。我正在使用上面的命令,因为一旦使用别名,它对我来说似乎更简单。
请注意,正如@Annihilannic 所提到的,如果您在 mosh 会话中使用 tmux/screen,那么在您终止 mosh 会话后,那些 tmux/screen 会话仍然存在。所以你仍然可以附加到它们(所以你真的不会因为杀死 mosh 会话本身而损失太多)。
这里声称杀死mosh-server
是唯一选择的答案在很大程度上已经过时,因为我们可以使用criu
andreptyr
来恢复和重新附加任意进程。
更不用说现在我们只能kill -USR1 mosh-server
以干净和安全的方式杀死分离的会话,而无需求助于不安全的who
输出或繁琐的命令来避免杀死我们自己的会话。
在 Michael R. Hines的回答旁边criu
,还有一个稍微“轻量级”的reptyr
,可用于重新附加由mosh-server
(即不是mosh-server
自身)启动的进程。我通常使用
pstree -p <mosh-server PID>
列出分离的 mosh-server 下的进程树,然后
reptyr PID
将所需的进程重新附加到我当前的终端。在对我关心的所有进程重复该过程后,我
kill -USR1 <mosh-server PID>
而我注意只杀死我知道是我的会话(共享系统)。
使用ps命令获取正在运行的任务列表或使用 ps -ef | grep 莫什
使用以下命令终止 mosh PID:
kill <pid>
此外,要关闭所有 mosh 连接,您可以:
请注意,如果您当前通过 mosh 连接,那么这也会断开您的连接
kill `pidof mosh-server`