196

How do I reattach to a detached mosh session or otherwise get rid of

Mosh: You have a detached Mosh session on this server (mosh [XXXX]).

i.e. what's the mosh equivalent of

screen -D -R

or possibly

screen -wipe

Furthermore, where can this answer be found in documentation?

John Baber-Lucero
  • 2,556
  • 3
  • 16
  • 19
  • 1
    Normally Mosh reconnects sessions (or tries to) if they are disconnected. When you enter new input it will try to reconnect (for flakey connections, or switching connections). For followers, this "detached Mosh session" occurs when you hard kill a client window. – rogerdpack Jan 31 '22 at 18:27

7 Answers7

235

For security reasons, you can not reattach, see https://github.com/keithw/mosh/issues/394

To kill the detached session, use the PID number displayed in that message (that's the 'XXXX' part.) For example, if you see --

Mosh: You have a detached Mosh session on this server (mosh [12345]).

And can run this command:

kill 12345

Also, to close all mosh connections you can:

kill `pidof mosh-server`

Note that if you are currently connected via mosh, this last command will also disconnect you.

varta
  • 3,296
  • 1
  • 17
  • 18
  • 35
    @artfulrobot Because there’s a chance that the detached session belongs to a mosh-client that’s still alive somewhere. Mosh sessions roam and can survive through a suspend/resume (e.g., “Hibernation”) cycle. The problem mosh does not (and cannot easily) solve is detecting that the client machine restarted without gracefully closing the mosh session. – binki Jan 12 '14 at 04:18
  • 7
    Is there a reason not to `killall mosh-server` instead? Especially since pidof and killall are really the same thing anyway. – Jordan Aug 14 '14 at 12:48
  • 7
    @Jordan: On some systems (Solaris, for example), `killall` does *exactly* what it says. – Dennis Williamson Jan 12 '15 at 15:44
  • 4
    If you are connected over mosh and you run `killall mosh-server` you will be disconnected. – 0xcaff Jun 09 '17 at 21:40
  • 2
    @0xcaff if you are connect over mosh and run `kill \`pidof mosh-server\`` you will be detached just the same – David Sep 12 '18 at 03:24
  • 1
    kill all but the active session: `pgrep mosh-server | grep -v $(ps -o ppid --no-headers $$) && xargs kill || echo "no active sessions to kill"` – rubo77 Nov 11 '19 at 08:47
  • I'm receiving `-bash: kill: (11628) - No such process`. – Iulian Onofrei Dec 23 '20 at 14:11
34

To my amazement, I used CRIU (https://criu.org) to checkpoint and restart a mosh client and it worked.

Shocking.

Find your mosh-client's PID:

$ ps -ef | grep mosh

Then, install CRIU according to their instructions.

Then, checkpoint it like this:

$ mkdir checkpoint

$ sudo ./criu dump -D checkpoint -t PID --shell-job

Then, restore it:

$ sudo ./criu restore -D checkpoint --shell-job

And, there it is. Your mosh client is back.

One thing to note, however, is that if your laptop reboots (which is the whole point of what we're trying to protect against), mosh uses a monotonic clock to track time on the client side, which doesn't work across reboots. This will NOT work, however, if your laptop just flat out crashes it won't work because mosh sequence numbers will be out of sync with the version that was checkpointed (the binary will resume, but communication will stop).

In order to fix this, you need to tell mosh to stop doing that and download the mosh source code. Then, edit this file:

cd mosh

vim configure.ac

Then, search for GETTIME and comment out that line.

Then do:

autoreconf # or ./autogen.sh if you've just cloned it for the first time

./configure

make

make install

After that, your CRIU-checkpointed mosh client sessions will survive reboots.

(Obviously you'd need to write something to perform the checkpoints regularly enough to be useful. But, that's an exercise for the reader).

Community
  • 1
  • 1
Michael Galaxy
  • 1,213
  • 14
  • 17
  • 1
    Be sure to type 'CTRL-L' to refresh the screen's output after restore. – Michael Galaxy Apr 16 '16 at 04:15
  • 6
    Out of sheer curiosity, is there a practical benefit of restoring the mosh client session that I am missing? I run tmux on mosh and can just relaunch mosh on the client and reconnect the tmux...is there a benefit of doing this other than its cool (which it really really is!)? – eskhool Nov 16 '16 at 15:52
  • 1
    The long answer: https://github.com/mobile-shell/mosh/issues/394 The short answer is, yes: One should not need a tmux session if the mosh-server daemon is already running on the target server. It not only leaves dangling mosh daemons lying around, but its another set of keystrokes that we shouldn't have to type in the first place. – Michael Galaxy Nov 18 '16 at 05:26
  • 3
    _Mosh is a substitute (in some cases) for SSH, not for screen._ [quoth keithw (mosh author) on github](https://github.com/mobile-shell/mosh/issues/394#issuecomment-15596586) – törzsmókus Sep 04 '17 at 09:18
30

I realize this is an old post, but there is a very simple solution to this, as suggested by Keith Winstein, mosh author, here: https://github.com/mobile-shell/mosh/issues/394

"Well, first off, if you want the ability to attach to a session from multiple clients (or after the client dies), you should use screen or tmux. Mosh is a substitute (in some cases) for SSH, not for screen. Many Mosh users use it together with screen and like it that way."

Scenario: I'm logged into a remote server via mosh. I've then run screen and have a process running in the screen session, htop, for example. I lose connection (laptop battery dies, lose network connection, etc.). I connect again via mosh and get that message on the server,

Mosh: You have a detached Mosh session on this server (mosh [XXXX]).

All I have to do is kill the prior mosh session

kill XXXX

and reattach to the screen session, which still exists.

screen -r

Now, htop (or whatever process was running) is back just as it was without interruption.This is especially useful for running upgrades or other processes that would leave the server in a messy, unknown state if suddenly interrupted. I assume you can do the same with tmux, though I have not tried it. I believe this is what Annihilannic and eskhool were suggesting.

007
  • 401
  • 4
  • 4
15

As an addition to Varta's answer, I use the following command to close all mosh connections except the current one:

pgrep mosh-server | grep -v $(ps -o ppid --no-headers $$) | xargs kill

  • 2
    In case, there is no old mosh session, xkill will throw an error. Better use `pgrep mosh-server | grep -v $(ps -o ppid --no-headers $$) && xargs kill || echo "no active sessions to kill"` – rubo77 Nov 11 '19 at 08:44
11

As @varta pointed out, the mosh owners are very against reattaching from different clients for security reasons. So if your client is gone (e.g. you restarted your laptop) your only option is to kill the sessions.

To kill only detached sessions you can use the following line (which I have as an alias in my .bashrc).

who | grep -v 'via mosh' | grep -oP '(?<=mosh \[)(\d+)(?=\])' | xargs kill

That command depends on the fact that who lists connected users including mosh sessions, only attached mosh sessions have "via mosh", and that mosh sessions have their pid in square brackets. So it finds the pids for just the detached mosh sessions and passes them to kill using xargs.

Here is an example who result for reference:

$ 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)

An alternative is to use the mosh-server environment variable MOSH_SERVER_SIGNAL_TMOUT. You can set it to something like 300 in your .bashrc on the server side. Then if you do a pkill -SIGUSER1 mosh-server it will only kill mosh-servers that have not been connected in the last 300 seconds (the others will ignore the SIGUSER1). More info in the mosh-server man page. I am using the command above because, once aliased, it seems simpler to me.

Note, as mentioned by @Annihilannic, if you are using tmux/screen inside your mosh sessions then those tmux/screen sessions are still around after you kill the mosh sessions. So you can still attach to them (so you really don't lose much by killing the mosh sessions themselves).

studgeek
  • 14,272
  • 6
  • 84
  • 96
7

The answers here claiming that killing mosh-server is the only option are largely obsolete, as we can use criu and reptyr to recover and reattach arbitrary processes.

Not to mention that nowadays we can kill -USR1 mosh-server to only kill detached sessions in a clean and safe way, without resorting to unsafe who output or cumbersome commands to avoid killing our own session.

Next to the criu answer from Michael R. Hines, there is the slightly more "light-weight" reptyr which can be used to reattach processes started by mosh-server (i.e. not the mosh-server itself). I typically use

pstree -p <mosh-server PID>

to list the tree of processes under the detached mosh-server, and then

reptyr PID

to reattach the desired process to my current terminal. After repeating the procedure for all processes I care about, I

kill -USR1 <mosh-server PID>

whereas I take care to only kill sessions I know are mine (shared system).

Irfy
  • 9,323
  • 1
  • 45
  • 67
-2

Use ps command for getting the list of running task or use ps -ef | grep mosh

Kill the mosh PID using this command:

kill <pid>

Also, to close all mosh connections you can:

Note that if you are currently connected via mosh, then this also disconnect you

kill `pidof mosh-server`
Pankaj Chauhan
  • 1,623
  • 14
  • 12