T S Vallender

Pairing with tmux

Pairing is great. It’s a fantastic way to share knowledge, increase code quality and reduce or remove the need for formal code review. If you’re working remotely (as I do) however, it can sometimes be a less smooth process than might be desirable. The most common way to do this is screen sharing, which can be fine for a short period, but it doesn’t take long for the warts to show: you’re limited to the other person’s preferences for fonts and sizes, switching drivers is awkward, you can’t copy and paste and much software limits you to sharing one screen at a time.

tmux is a fantastic piece of software with a great many benefits (“tabs” in your terminal, persisting programs across sessions…), but one of the best is its ability to share a session. By default, however, the process of sharing a tmux session leaves something to be desired. Others have tackled this problem already—see wemux, for example—but I wanted to keep things as minimal as possible. Add the smallest layer possible on top of tmux, just enough to remove the friction.

The goal here is to allow someone to connect to my machine via SSH and join my tmux session. The main outcome was a script I have aliased to “tp”. This gives me the following commands: “tp new” to start tmux, without sharing, “tp sharero” to share the existing session read-only, “tp sharerw” to share the session with write access, and “tp unshare” to share the stop sharing and kick the other user out of my PC!

So, how do we do this? tmux shares sessions by using a socket multiple users can connect to. This means we need to choose a consistent location for that socket (I went with /var/tmux_share/shared). I then added a user to my system for others to connect with. Using a single user for this means we can configure it to behave exactly as we wish for pairing. This user, my user, and any other users we want to pair with should also be members of the “tmux” group, which we use for setting the correct permissions on the socket.

You can see the entire script here.

Now, much as I might trust my colleagues I don’t really want to give them access to do things on my machine I can’t see: when they SSH on, they should automatically join the session. If there is no shared session, they shouldn't be allowed to join. We achieve this by having the pairing user’s .bashrc run the following:

SOCKET_PATH="/var/tmux_share/shared"

# Connect to tmux if a session exists
tmux -S $SOCKET_PATH attach -t shared

# If a session didn't exist, delete the socket we created
[ $? -ne 0 ] && rm -f $SOCKET_PATH

# Exit, either when exiting tmux or after failing to connect
exit

Of course you need to make sure you have any necessary port forwarding set up, but otherwise that’s about it. I’m now in the habit of always working in a tmux session I start with “tp new”. If I want to start pairing, I just run “tp sharerw” and ask them to SSH on over. This works best while on voice chat, and then you can also still use screen sharing to share a web browser or GUI.

As with any approach, there are of course limitations. The primary one I’ve found is working around differences in terminal size. There are a few different options to deal with this in your .tmux.conf, but in my opinion the least bad one is to set 
set -g window-size smallest
which will limit the larger terminal to the size of the smaller, rather than continuously resizing content.

Updated at 2023-10-06 08:36 | 2023-10-05 21:14