Tmux is great

Tmux is a great application with a few super-cool uses. You can get really deep into configuring it, but I tend to use the default options so that I can install it and start using it on any machine and get a similar experience. Here are a few of my favourite uses:

Persistent ssh sessions

This is far and away the best use of tmux. I typically use mosh to make sure my ssh sessions don't crash.

Here's a brief explanation of why this is important. If I'm running a long job on a remote machine,  like a database migration or a backup or something, it can be crucial that the job is not interrupted. But if my network on the local machine fails even for a moment, it can crash the ssh session and thus the job.

Mosh fixes this by running a daemon on the remote machine that can restore sessions. It's really quite clever. But not every machine has mosh, and even when I use mosh I like to use tmux alongside so I can have a scrollback buffer in my terminal (see below).

So tmux is a lightweight way to ensure your job doesn't fail. Simple open tmux on the remote machine and start your job. There is an added benefit that you can open another shell while the long-running job does its thing without needing to ssh in again.

If your ssh session fails in the middle (or you close your terminal window by accident), your job continues to run in the tmux session on the server! Further, if you log back into the machine as the same user and run tmux attach, you will re-attach to the same shell and be able to see the job! A nice command to run when you log into a machine is tmux attach || tmux, which will either attach to an existing session if it exists, or open a new tmux session as a fallback.

To exit a tmux session, you just need to type exit one additional time while closing the shell.

Opening multiple sessions

As I said above, tmux is great because you can run more than one shell in the same window. On my local machine, I don't bother with this because multiple windows are nicer to work with. But tmux is pretty powerful and it shines even more in an ssh session. Plus, if you're using some flavour of Linux without windows, it can be nice to know about tmux commands.

The bare minimum to know about is Ctrl+b c (to open a new session in the tmux window), Ctrl+b n (to move to the next window), Ctrl+b N (to move to the previous window), Ctrl+b 2 (to move to session #2), and Ctrl+b d (to detach from the tmux session).

If you detach from a tmux session, you drop back to your regular shell. You can run tmux to open a different tmux window, or tmux attach to rejoin the still-running tmux session you had detached from.

Opening tmux as root, then sudoing to the user you want

At my previous job, I very often ran sudo tmux attach || sudo tmux upon sshing into a machine. Why? We treated our web server like shared hosting - every website was isolated with a user account and a home directory. In retrospect, I maybe applied this a little too heavily, but I have used this pattern in a smaller way on other machines in the past few years.

So if I typically am changing users a lot on a box, running tmux as root lets me change to other user accounts just like this:

Ctrl+b c # open a new window
su - newuser # open a login shell for the user I want to switch to

Tmux is even greater because then I can use Ctrl+b n to cycle through the different user sessions. Such fun!

Scrollback buffer

Tmux lets you scroll back through the text that has been displayed on your terminal. This is like a retroactive version of less - very helpful!

Ctrl+b [ will open scrollback mode, and Ctrl+c will leave it. Arrow keys let you navigate through the buffer. I think PageUp and PageDown go faster. It can be kind of slow to scroll through, perhaps because there's a command I don't know about that makes it faster.

Binding rspec, tmux, and vim

OK, I'll admit, I used this for a while and eventually stopped. But there's a nifty trick to make your rspec testing a bit faster if you're doing a lot of it and you use vim.

First, install https://github.com/thoughtbot/vim-rspec. I recommend adding these mappings to your vimrc:

let mapleader = ','
map <Leader>t :call RunCurrentSpecFile()<CR>
map <Leader>s :call RunNearestSpec()<CR>
map <Leader>l :call RunLastSpec()<CR>
map <Leader>a :call RunAllSpecs()<CR>

Then you have to open a terminal with tmux active in your rails root directory. In a different terminal, open the spec file you're working on. Make your changes, then in command mode type ,t to run the whole file in rspec. It will ask you a few questions to determine which tmux window/session to attach to, then it'll run your spec!

Once you do the initial test, ,s becomes your friend, because it will run the spec nearest the line you're on and it won't ask you which tmux to attach to. This is probably the most efficient rspec testing setup, but because of the cognitive load to get into it I haven't been using it full time recently. Perhaps that will change someday, but that's why it's at the bottom of the list for now.

 

Add new comment