Python testing tutorial using pytest
2021-02-13
Improvements in Deep Q Learning: Dueling Double DQN, Prioritized Experience Replay, and fixed Q-targets
2021-04-20
Show all

tmux basics tutorial

What’s tmux?

tmux’s authors describe it as a terminal multiplexer. Behind this fancy term hides a simple concept: Within one terminal window you can open multiple windows and split-views (called “panes” in tmux lingo). Each pane will contain its own, independently running terminal instance. This allows you to have multiple terminal commands and applications running visually next to each other without the need to open multiple terminal emulator windows.

On top of that tmux keeps these windows and panes in a session. You can exit a session at any point. This is called “detaching”. tmux will keep this session alive until you kill the tmux server (e.g. when you reboot)2. This is incredibly useful because at any later point in time you can pick that session up exactly from where you left it by simply “attaching” to that session.

If you’ve ever worked with remote servers or a Raspberry Pi over ssh you can guess where this will be useful: When you lose your ssh connection the tmux session will simply be detached but will keep running on the server in the background including all the processes that run within your session. To continue your session simply ssh to the server again and attach to the running session.

But tmux is not only helpful when working on a remote machine. Not only for its window management features but also for the session handling. Personally I find myself detaching from sessions when I’m switching context. I’ll just start a new session for my new task and attach to the old session whenever I want to continue with my old task.

You see that tmux basically offers two big features: Window management in your terminal and session management. If you are familiar with GNU Screen this is nothing new. Think of tmux as an easier-to-use and a little more powerful alternative to Screen (obviously I’m being opinionated here).

Enough with the talking already. Let’s get our hands ready in the hands-on guide!

Getting Started

This hands-on guide will get you up and running with tmux pretty quickly. It will only cover the basic features which should be more than enough to get started and be productive with tmux. Simply open your terminal and follow the instructions.

Installation

Fortunately installing tmux is pretty straightforward on most distributions a simple sudo apt-get install tmux (Ubuntu and derivatives) or brew install tmux (Mac) should be sufficient.

Starting Your First Session

For your first session simply start tmux with a new session:

tmux

This will create a new tmux session with a nice all-green status bar at the bottom:

vanilla tmux on startup

The status bar is an important part of tmux. Apart from the currently opened windows (on the left) it also shows some system information like date and time (on the right). The status bar can also be customized and I’ve seen some really fancy stuff around (upcoming calendar events, battery status, to name a few) but this is something we’ll leave for later.

Splitting Panes

Now that we’ve created our first session we can get a feeling for panes. When you create a new session, tmux will by default start with one window and a single panel inside. We want a nice split-screen, so let’s split this bad boy.

All commands in tmux are triggered by a prefix key followed by a command key (quite similar to emacs). By default, tmux uses C-b as prefix key. This notation might read a little weird if you’re not used to it. In this emacs notation C- means “press and hold the Ctrl key”. Thus C-b simply means press the Ctrl and b keys at the same time.

The shortcut to split panes into a left and a right pane is C-b %. Remembering what I’ve just told you about tmux’s sequence of prefix and command key this means to split your single pane into a left and a right pane you press Ctrl and b at the same time, release both, and then type the % key. Voilà! You’ve just invoked your first tmux command and split your pane in two.

tmux with two split panes

Where there’s a split into left and right, there’s also a split into top and bottom pane. To split a pane into top and bottom panes use the C-b " shortcut.

Right now we’re trapped in the newly created pane. But we really really want to go back to the left one. Easy peasy: Switching to a different pane uses the C-b <arrow key> shortcut, where <arrow key> is the arrow key pointing to the pane you want to switch to. In our case we want to switch to the panel on the left so it’s C-b left for us. Just once more, so that we fully understand this: This means you press Ctrl and b (your prefix) followed by the left arrow key to get to the pane on the left.

You can now go ahead and split each of your new panels even further. Feel free to experiment and split your panes like a maniac to get a feeling for it.

Closing Panes

Closing a pane is as simple as closing a regular terminal session. Either type exit or hit Ctrl-d and it’s gone.

Creating Windows

Windows in tmux can be compared to creating new virtual desktops; if you’ve ever worked with one of the major Linux deskop environments (KDE, Gnome) you’ll hopefully find this analogy helpful.

Creating new windows is as easy as typing C-b c (one last time: that’s Ctrl and b at once, then c). The new window will then be presented to you in tmux’s status bar.

tmux with two windows

You can now divide the pane in your new window as you like. Or don’t. That’s up to you.

To switch to the previous window (according to the order in your status bar) use C-b p, to switch to the next window use C-b n. If you’ve created many windows you might find it useful to go to a window directly by typing its number (the status bar will tell you which window has which number), just use C-b <number> where <number> is the number in front of the window’s name in your status bar.

Session Handling

If you’re done with your session you can either get rid of it by simply exiting all the panes inside or you can keep the session in the background for later reuse.

To detach your current session use C-b d. You can also use C-b D to have tmux give you a choice which of your sessions you want to detach. This will detach your session but will leave you’re doing in that session running in the background.

Now that your session is detached you can pick it up from where you left it at any later point in time. To re-attach to a session you need to figure out which session you want to attach to first. Figure out which sessions are running by using

tmux ls

This will give you a list of all running sessions, which in our example should be something like

0: 2 windows (created Sat Aug 15 17:55:34 2015) [199×44] (detached)

To connect to that session you start tmux again but this time tell it which session to attach to:

tmux attach -t 0

Note that the -t 0 is the parameter that tells tmux which session to attach to. “0” is the first part of your tmux ls output.

If you prefer to give your sessions a more meaningful name (instead of a numerical one starting with 0) you can create your next session using

tmux new -s database

This will create a new session with the name “database”.

You could also rename your existing session:

tmux rename-session -t 0 database

The next time you attach to that session you simply use tmux attach -t database. If you’re using multiple sessions at once this can become an essential feature.

And that’s it! Congratulations, you’ve just completed your first tmux session and got your hands dirty with its window and session management. Yes, there’s more stuff tmux can do. But what you’ve just learned should be everything to start using tmux in the future.

Why tmux?

A response that I get quite often is: “Great, I get it. But why should I use tmux and its weird key combinations instead of just using iTerm2?”

And you’re right, when it’s only basic window management, iTerm for Mac supports tabs and panes as well. For Linux there’s Terminator. So why would anyone feel the urge to learn some archaic technology in this day and age?

But you’re missing out. There are a couple of reasons why I favor tmux over iTerm et al.:

  • session handling: detaching from and attaching to sessions helps me with context switching and remote working
  • platform independence: I can use tmux on my Macbook, my Linux notebook, Cloud servers, Raspberry Pis, BeagleBones, etc.
  • customizable: there are many ways I can customize the look and behavior of my tmux environment. And I can sync this across different platforms using a simple dotfile
  • street credibility: you don’t want others to call you a lamer, do you? 😛

Moving on

If you’re curious now to learn what else tmux can do that’s a great thing. And luckily most of the stuff is quite simple to discover. Just type C-b ? to see a list of all available commands and start experimenting.

Some of the commands that I’m using myself quite often are:

  • C-b z: make a pane go full screen. Hit C-b z again to shrink it back to its previous size
  • C-b C-<arrow key>: Resize pane in direction of <arrow key>
  • C-b ,: Rename the current window

On top of that there are plenty of resources out there that help you getting further with tmux. People like me are blogging about their tmux experience and share what they’ve discovered. You can find people sharing their tmux configurations in their dotfiles repos on Github. There’s even a book by Brian Hogan dedicated to tmux.

For now it’s best to discover some stuff on your own. Experiment, fool around and maybe try to use tmux in your daily work. It takes a while to get used to and you’ll probably feel slow in the very beginning. I can only encourage you to keep using it. Get a feeling for its functionality and in no time you’ll find out that your work with the terminal will be pure bliss and insanely fast.

Customizing tmux

Customizing tmux is as easy as editing a text file. tmux uses a file called tmux.conf to store its configuration. If you store that file as ~/.tmux.conf (Note: there’s a period as the first character in the file name. It’s a hidden file) tmux will pick this configuration file for your current user. If you want to share a configuration for multiple users (e.g. if you should feel the urge to start tmux as super user (please think about this carefully!)) you can also put your tmux.conf into a system-wide directory. The location of this directory will be different accross different operating systems. The man page (man tmux) will tell you the exact location, just have a look at documentation for the -f parameter.

Less awkward prefix keys

Probably the most common change among tmux users is to change the prefix from the rather awkward C-b to something that’s a little more accessible. Personally I’m using C-a instead but note that this might interfere with bash’s “go to beginning of line” command. On top of the C-a binding I’ve also remapped my Caps Lock key to act as Ctrl since I’m not using Caps Lock anyways. This allows me to nicely trigger my prefix key combo.

To change your prefix from C-b to C-a, simply add following lines to your tmux.conf:

# remap prefix from 'C-b' to 'C-a'
unbind C-b
set-option -g prefix C-a
bind-key C-a send-prefix

Sane Split Commands

Another thing I personally find quite difficult to remember is the pane splitting commands. I mean, seriously? " to split vertically and % to split horizontally? Who’s supposed to memorize that? I find it helpful to have the characters as a visual representation of the split, so I chose | and - for splitting panes:

# split panes using | and -
bind | split-window -h
bind - split-window -v
unbind '"'
unbind %

Easy Config Reloads

Since I’m experimenting quite often with my tmux.conf I want to reload the config easily. This is why I have a command to reload my config on r:

# reload config file (change file location to your the tmux.conf you want to use)
bind r source-file ~/.tmux.conf

Fast Pane-Switching

Switching between panes is one of the most frequent tasks when using tmux. Therefore it should be as easy as possible. I’m not quite fond of triggering the prefix key all the time. I want to be able to simply say M-<direction> to go where I want to go (remember: M is for Meta, which is usually your Alt key). With this modification I can simply press Alt-left to go to the left pane (and other directions respectively):

# switch panes using Alt-arrow without prefix
bind -n M-Left select-pane -L
bind -n M-Right select-pane -R
bind -n M-Up select-pane -U
bind -n M-Down select-pane -D

Mouse mode

Although tmux clearly focuses on keyboard-only usage (and this is certainly the most efficient way of interacting with your terminal) it can be helpful to enable mouse interaction with tmux. This is especially helpful if you find yourself in a situation where others have to work with your tmux config and naturally don’t have a clue about your key bindings or tmux in general. Pair Programming might be one of those occasions where this happens quite frequently.

Enabling mouse mode allows you to select windows and different panes by simply clicking on them. I’ve found that this might mess a little bit with simply selecting text in your terminal using the mouse. You might experience the same, depending on your environment. So you should consider if this configuration is something that’s worth it for your use case:

# Enable mouse control (clickable windows, panes, resizable panes)
set -g mouse-select-window on
set -g mouse-select-pane on
set -g mouse-resize-pane on

Update for tmux 2.1:
As Jon Lillie pointed out in the comments, mouse mode has been rewritten in tmux 2.1. Once you are on tmux 2.1 (or later) you can activate the new mouse mode with a single command:

# Enable mouse mode (tmux 2.1 and above)
set -g mouse on

The new mode is a combination of all the old mouse options and fixes the text selection issues as well.

Stop renaming windows automatically

I like to give my tmux windows custom names using the , key. This helps me naming my windows according to the context they’re focusing on. By default tmux will update the window title automatically depending on the last executed command within that window. In order to prevent tmux from overriding my wisely chosen window names I want to suppress this behavior:

# don't rename windows automatically
set-option -g allow-rename off

Changing the look of tmux

Changing the colors and design of tmux is a little more complex than what I’ve presented so far. You’ll want tmux to give a consistent look which is why you most likely have to change the looks of quite a lot of elements tmux displays. This is why changes to the design often result in plenty of lines in your config. I can only recommend to put these into their own identifiable section within your tmux.conf to be able to change this block of config without accidentaly ripping out some of your precious custom key bindings. I’m using comments, starting with a # character to make it visible where the design changes start.

Credit where credit is due: I did not create the following design. /u/dothebarbwa was so kind to publish it on /r/unixporn so it’s his effort and all thanks have to go out to him. Thanks!

Depending on your color scheme (I’m using base16-ocean-dark) your resulting tmux will look something like this:

themed tmux
######################
### DESIGN CHANGES ###
######################

# loud or quiet?
set -g visual-activity off
set -g visual-bell off
set -g visual-silence off
setw -g monitor-activity off
set -g bell-action none

#  modes
setw -g clock-mode-colour colour5
setw -g mode-style 'fg=colour1 bg=colour18 bold'

# panes
set -g pane-border-style 'fg=colour19 bg=colour0'
set -g pane-active-border-style 'bg=colour0 fg=colour9'

# statusbar
set -g status-position bottom
set -g status-justify left
set -g status-style 'bg=colour18 fg=colour137 dim'
set -g status-left ''
set -g status-right '#[fg=colour233,bg=colour19] %d/%m #[fg=colour233,bg=colour8] %H:%M:%S '
set -g status-right-length 50
set -g status-left-length 20

setw -g window-status-current-style 'fg=colour1 bg=colour19 bold'
setw -g window-status-current-format ' #I#[fg=colour249]:#[fg=colour255]#W#[fg=colour249]#F '

setw -g window-status-style 'fg=colour9 bg=colour18'
setw -g window-status-format ' #I#[fg=colour237]:#[fg=colour250]#W#[fg=colour244]#F '

setw -g window-status-bell-style 'fg=colour255 bg=colour1 bold'

# messages
set -g message-style 'fg=colour232 bg=colour16 bold'

A Word of Caution

I took care of explaining and documenting all suggested changes in this post to make it easy for you to understand what they do and to decide if this is something you want for your tmux.conf as well.

If you do your amount of research on the web you will find plenty of heavily customized tmux configurations. It’s really tempting to just copy those and call it a day. Please, for your own sake, don’t do that. Trust me, I’ve been there. I can only recommend that you start out with a plain tmux configuration and add modifications one by one. This is the only way to ensure that you are fully conscious of all the changes you have made. And this is the only way you will actually learn something about tmux along the way. That said: go ahead and look up config files others have published. Take these as source of inspiration and choose wisely what you want to take for your own config.

There is some really interesting stuff out there. I’ve seen people doing pure magic with their status bars, displaying all kinds of system information that might be interesting. To apply those changes you’ll most likely exceed the simple one-liners I’ve presented in this post. Often there are special scripts involved that need to be loaded, accompanied by multiple lines of configuration changes. I don’t want to discourage you from using these. Just be aware that this is a more advanced topic where you can certainly screw some stuff up. Make sure to backup your config accordingly.

Reference:

https://www.hamvocke.com/blog/a-quick-and-easy-guide-to-tmux/

Amir Masoud Sefidian
Amir Masoud Sefidian
Data Scientist, Machine Learning Engineer, Researcher, Software Developer

Comments are closed.