Making my tmux life easier

[Tweet : ADN : nvALT]

Have you heard of tmux? Do you ache for terminal mutiplexing and persistent shell sessions? If not, you can probably skip this post. Hang tight, I have something more generally palatable in the works. In the meantime, if you want to read up, head to the tmux homepage.

I’ve been enjoying tmux for a while now. I was never a big screens user, but I’d played with it as a basic replacement for nohup on remote sessions. tmux just clicked for me when I sat down to figure it out, though, and I’ve been using it in various ways since.

I’m aware that there’s a method to the madness behind the varying flags used when calling “attach” vs. “new,” for example, but I always get my -s, -t, and -n switched up. I wrote a wrapper to help me out.

Because it only wraps the “attach” and “new” commands, this would generate nested sessions if run within tmux. It’s only really handy if you detach from your sessions regularly instead of just flying between multiple sessions/windows like a pro. I use tmux primarily for setting up remote connections and running on remote servers, so I drop back to Terminal frequently and jump back to sessions as needed.

When sourced in your .bash_profile or .zshrc, it gives you a tm command that you can run with one or two arguments. The first argument is always a session name, the second can specify a window. If the session name you provide matches an existing session (partial names work), you’ll be connected to it, and optionally to a specific window in the session if you supply that argument.

The window name can be partial, too. So if I have a session named “jekyll” and a window called “dev,” I can connect to that window just by running tm jek dev, or just tm j if there are no other sessions starting with “j” and “dev” was my last-used window. If multiple sessions or windows match your partial, the first one alphabetically will be selected.

If no matches are found for the session name, a new session will be created and attached. The second argument can be used to name the first window upon connection.

Here’s the script, do with it what you will.

Just for fun

Here’s a quick snippet you can use in your bash_profile to display a “session:window” banner when you connect to a new window. It uses Figlet, but you can do whatever you want with the $sessionname and $winname variables.

# print a banner for the current window name within tmux
tm-win-banner() {
  local winname sessionname
  if [[ -n $TMUX ]]; then
    sessionname=`tmux list-sessions | grep attached | awk -F: '{print $1}'`
    winname=`tmux list-windows | grep --color=never -E '^\d+: (.*)\*'| awk '{ print $2 }' | tr -d '*'`
    figlet -w `tput cols` -f graffiti "$sessionname:$winname"
  fi
}

When run, this gives me:

You can also split the session and window names up and use them in a PROMPT_COMMAND, but if you’re in tmux you already have a status bar. If you use iTerm 2’s tmux integration, all tabs and windows share the same session, so it’s ultimately kind of pointless. Whatever.

tm-session() {
  local sessionname
  if [[ -n $TMUX ]]; then
    sessionname=`tmux list-sessions | grep attached | awk -F: '{print $1}'`
    echo -n $sessionname
  fi
}

tm-window() {
  local winname
  if [[ -n $TMUX ]]; then
    winname=`tmux list-windows | grep --color=never -E '^\d+: (.*)\*'| awk '{ print $2 }' | tr -d '*'`
    echo -n $winname
  fi
}

Ryan Irelan has produced a series of shell trick videos based on BrettTerpstra.com posts. Readers can get 10% off using the coupon code TERPSTRA.