26

I recently switched from using screen to tmux (obtained through macports), as I like the feature set more. However, I can't seem to get tmux to reattach from an alternate location, like I can screen.

At home on my mac, I will open up iTerm2, my default shell is zsh, and I will begin a tmux session with tmux. I get all my spits set up, ssh'd into the proper servers, etc., and work for a while. Time to go to work. <C-a> d - tmux detaches.

I get to work, where I use a windows xp machine. I fire up putty, ssh into my mac back at home, attempt a tmux attach, and get an error message:

no sessions

I cannot seem to determine why this would happen. I am not afraid to dig into this, but don't even know where to start. Thoughts?

P.S. I have already removed my .tmux.conf file, so it's using the default config.

kenny
  • 3,439
  • 3
  • 26
  • 31

4 Answers4

45

In my case, apparently temp folder was cleaned.
This blog post helped me recover my “lost” session:

I finally got the solution: sending the signal 10 forced tmux to recreate sockets. After that I could run tmux again without losing my session:

$ killall -10 tmux
Community
  • 1
  • 1
Dan Abramov
  • 264,556
  • 84
  • 409
  • 511
  • 3
    I had this same issue today, and came across the same blog! It works, but I was confused about *why* it works. It turns out that signal 10 is a *user-defined signal*, and [tmux says it will "recreate the server socket on SIGUSR1"](https://github.com/ThomasAdam/tmux/blob/814e40522cb611895e84fc2aaf58d5d0ca9ba348/CHANGES#L552). – DaoWen Jan 19 '15 at 19:44
  • 1
    This worked for me, but *not* when I had a second tmux session open: I think the sockets clashed meaning that the original session could not recreate them. – spookypeanut May 21 '15 at 05:58
  • 1
    The **parent directory** is not recreated before the sockets, you have to do it before sending the kill signal. – bufh Jan 26 '16 at 12:04
  • The blog is not available any more. The kill -10 works well indeed. Just curious the reason, and how to resolve this issue ? – Yi Sun Oct 15 '21 at 02:32
23

tmux stores its server socket in a directory under the directory specified by the TMPDIR environment variable.

In your GUI session you probably end up with a TMPDIR that points to somewhere under /var (e.g. /var/folders/mV/mVip4IQ4EXOriTiLJmeSuk+++Tc/-Tmp-/).

When you are logged in through SSH, you probably end up without a TMPDIR set, so tmux looks under /tmp/ for its socket.

On a 10.6 system, here is my TMPDIR with zsh/Terminal, and with zsh/SSH:

% echo local: ${TMPDIR-unset}; ssh localhost 'echo remote: ${TMPDIR-unset}'
local: /var/folders/mV/mVip4IQ4EXOriTiLJmeSuk+++Tc/-Tmp-/
remote: unset

If you know the value you need to use for TMPDIR, you can specify it when attaching (or running some other tmux command outside of the session itself):

TMPDIR=/var/folders/mV/mVip4IQ4EXOriTiLJmeSuk+++Tc/-Tmp-/ tmux attach

If you do not know the directory your GUI session was using you might be able to find it with something like this (the syntax is specific to zsh; it searches under /var/folders/ for a directory named -Tmp- that is owned by the current user):

echo /var/folders/**/*/-Tmp-(U/)

To avoid problems in the future, you might want to unset TMPDIR before starting your server (or set it to something that you can more easily predict).

Chris Johnsen
  • 214,407
  • 26
  • 209
  • 186
  • 6
    Running an `unset TMPDIR` prior to starting my tmux session did solve the problem. Huge props. – kenny Jan 30 '12 at 18:53
  • 2
    If you are trying to find the tmpdir in bash, try `find /var/folders -type d -name "-Tmp-" -user $(whoami) 2>/dev/null` This looks in /var/folders for a directory (d) with name "-Tmp-" owned by you. Since /var/folders will contain a lot of directories that will be permission denied, the stderr is also redirected to the bit bucket. Edit: premature enter – myeeshen Apr 10 '12 at 21:50
  • `TMPDIR=/var/folders/mV/mVip4IQ4EXOriTiLJmeSuk+++Tc/-Tmp-/ tmux attach` didn't work for me but `TMUX_TMPDIR=/var/folders/mV/mVip4IQ4EXOriTiLJmeSuk+++Tc/-Tmp-/ tmux attach` with a valid value for my TMPDIR found with the lsof command below. – Ricky Nelson Oct 04 '16 at 20:28
  • As an alternative, you can manually specify the location of the socket with `tmux -S /Users/yourname/.tmux-socket attach` or similar. (You need to use the same `-S` value when you create the session and each time you reattach to it.) Choosing a location in your home directory means the socket will not be purged out from under you. – bdesham Nov 15 '18 at 19:07
  • make sure you're not explicitly calling other shell programs in your init conf, such as `set-option -g default-command "reattach-to-user-namespace -l bash` calling bash might mess if you're also using bash. – EhevuTov Oct 04 '20 at 01:02
7

The -U option of lsof lists open socket files, so lsof -U | grep '^tmux' will list all of the sockets in use by tmux. If you're not logged in as the same user that started tmux, you will need to use sudo.

The last column of each row is the name of the file. The files you care about start with a /.

The rows you're looking for will look something like this:

tmux 1234  username 6u unix 0xffffffabcd123456 0t0 /private/var/folders/M8/M8tFwolmH08fOvJ+-35VI++++TM/-Tmp-/tmux-502/default
tmux 56789 username 6u unix 0xffffff123456789a 0t0 /private/tmp/tmux-502/default
Tyler Holien
  • 4,791
  • 2
  • 19
  • 14
2

I have a variation on the lsof suggestion that I have been using with some success to “recover” the TMPDIR variable which can help working around a bunch of annoyances. The advantage, I suppose, is that one can be a little more exacting about what lsof returns and easier to parse out the correct value (on the off-chance at some point some atypical chars, but still valid, ever output).

A quick, one-liner is:

$ lsof -Fn -d6 -aUc tmux | grep ^n | cut -c2-
/private/var/folders/_l/f_n8blps05xfnkw6fs3dcn_80000gp/T/tmux-502/default

I use the following script (could also be a function in ~/.bash_profile or other appropriate place I suppose):

#!/bin/bash

if [[ -z "${TMPDIR}" ]]; then
  while read line; do
      case $line in
      n*) line="${line#n}"
          export TMPDIR="${line%%/tmux-$(id -u)/*}"
          ;;
      esac;
  done < <(lsof -Fn -d6 -aUc tmux)
else
    echo ">> \$TMPDIR already defined: $TMPDIR" 1>&2
fi

https://gist.github.com/jps3/769d50a6a7611949473b

jps3
  • 21
  • 2