How do I reattach to a detached mosh session?
Solution 1:
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.
Solution 2:
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).
Solution 3:
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.
Solution 4:
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
Solution 5:
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).