What is it and what do you need it for?
If you are working with Linux remote machines on a daily basis, or simply are the kind of person who wants to work with his terminals in the most efficient way possible, you probably already heard of GNU screen. It is a terminal multiplexer, meaning that it allows you to access multiple virtual terminal sessions from inside a single physical terminal. How can this help you? Well, most commonly, it can help you in two situations:
- you want to work with six terminals on a remote machine;
How do you do it?
The classic way: you open up six terminals (or Putty sessions) and ssh to the remote machine on each one of them. Even if you have ssh keys configured and don’t have to introduce a password, it’s still a bummer. You still have to alt+tab or alt+# through six terminals and managing them can become a headache.
The terminal multiplexer way: you open up a terminal/putty session and ssh to the remote machine. There, you run screen, and open new virtual terminals (called windows) without having to ssh to the remote machine again. You manage you windows with simple shortcuts, and instead of six open applications, you have just one. - you want to have more terminals open on your screen at the same time, so you don’t have to switch through them to read each of their output;
Newly created windows can be arranged like multiple tabs in your terminal, but in addition, each window can be split into regions, such that you can see and access multiple terminals at once, having all of them in front of you. For example, one way I am using this is for logically separating my areas of work: I keep one window with multiple regions for writing code in different files, one window with multiple regions for testing my code (each executable will have its own region) and one window for reading log files.
Like screen, tmux is also a terminal multiplexer; I’ve never been a screen power user, so I won’t go ranting on why one of them is better than the other. If you’re interested, from what I’ve read the main things that differentiate tmux from screen are:
- it’s a server-client system – meaning that there is a server instance (started when tmux is first run) and the sessions you open are the clients; this allows you to even move windows from one session to another, or view a window from multiple sessions at the same time
- it can split panes vertically, not just horizontally
- it has a pane-synchronizing option, such that when you write something in a pane, it simultaneously writes the same thing in all the panes from the current window
- multiple paste buffers
- the option of choosing either vim or emacs key bindings
- some say it’s less resource hungry than screen (but I don’t think any real benchmarks have been run yet in this regard)
How to use tmux
Tmux probably isn’t going to be installed by default on your system, so you will first have to install it either using your favorite package manager (aptitude, yum, …) or by compiling the sources. These can be found on the tmux website. If you decide to compile from source, be aware that you will also need to have installed the development files for libevent (on RHEL, these are libevent-devel.i686 or libevent-devel.x86_64, depending on your platform).
After you installed it, you can simply run ‘tmux’ to start a new session:
$ tmux
To list all your running sessions:
$ tmux ls 0: 2 windows (created Thu Dec 22 15:07:17 2011) [237x54] (attached)
To attach from a detached session (we will see later how you can detach a session):
$ tmux attach [-d] [-t session_index]
If you specify the ‘-d’ option, it will detach the specified session and attach it to your current terminal. The session index is the identifier of the session you wish to attach to (you can find it with ‘tmux ls’).
As you can see, tmux now looks just like your basic terminal, with the exception of the green status bar on the bottom. To give commands to tmux, you can either enter the tmux command prompt (by pressing C-b : ) and issue the command or you can use a key binding associated with a command. Below are the most common key bindings I use (PS: you can reassign key bindings if they’re not good for you, see the next section):
- C-b c -> create a new window
- C-b 0 to 9 -> go to a window number
- C-b n -> go to the next window
- C-b p -> go to the previous window
- C-b ” -> split the current pane in two: top and bottom
- C-b % -> split the current pane in two: left and right
- C-b ←/→/↑/↓ -> move focus to other panes; if you want to move through multiple panes, you don’t have to press C-b and a directional key every time, just press C-b once and then quickly press multiple directional keys
- C-b C-o -> swap panes in counter-clockwise order
- C-d -> exit the current shell
- C-b, and while holding Ctrl, press ←/→/↑/↓ -> resize a pane
- C-b ! -> make the current pane a new window
- C-b d -> detach from the current session
- C-b Alt-1 to Alt-5 -> arrange panes in one of the five preset layouts: even-horizontal, even-vertical, main-horizontal, main-vertical, or tiled
- C-b ? -> see all key bindings
There are a few more bindings it’s very useful that you know. A tmux window may operate in two ways: the default mode, which gives you access to the terminal attached to the window, and the copy mode. The last one lets you select and copy some text from your window into a paste buffer, so that you can later paste the selection into another window/pane.
- C-b [ -> enter copy mode; press Space to start selection, Enter to copy the selection into a paste buffer and q to go back to the default mode
- C-b ] -> paste the contents of the last paste buffer
- C-b = -> interactively choose a paste buffer from which to paste the contents into the current terminal
However, there are some interesting commands that don’t have key bindings by default. To issue them, press ‘C-b :’, write the command and press Enter. Some useful commands are:
- set-option -g mouse-resize-pane on -> lets you rearrange the panes’ width and height using the mouse
- set-option -g mouse-select-pane on -> lets you select panes by left-clicking on them
- set-window-option -g mode-mouse on -> lets you use the mouse to enter copy mode, copy a selection by dragging and scroll with the mouse wheel
- set-window-option -g monitor-activity on -> tells tmux that it should monitor the activity on all windows
- set-window-option -g visual-activity on -> display a status line message when activity occurs in a window that has the monitor-activity option enabled
- set-window-option monitor-content match-string -> tells tmux to monitor the content in the window, looking to match the match-string pattern
- set-window-option visual-content on -> display a status line message when content is present in a window for which the monitor-content option is enabled
- set-window-option synchronize-panes on -> synchronizes what you write in a pane with the rest of the panes in a window
You can see all the available commands in tmux’s man page.
The configuration file
If you want some options to be persistent over multiple runs of tmux, you must write them in the tmux configuration file: either /etc/tmux.conf, which is the global configuration file (it applies to all users), or ~/.tmux.conf, which only applies to the current user. Here is the configuration file I use:
# use this if you want to set the prefix to C-a, like screen does # unbind C-b # set -g prefix C-a set -g history-limit 16384 # the number of lines you can search through in copy mode set -g buffer-limit 50 # number of paste buffers set -g base-index 1 # the window numbering will start from 1 instead of 0 # create a window with 4 panes by default # Be careful! if you do this you must start tmux with 'tmux attach' # if you start it with 'tmux' it will take you to a newly created session, # and you will have 2 sessions, as 'tmux' is equivalent to 'tmux new-session' new splitw -v -t 0 splitw -h -t 1 splitw -h -t 0 selectp -t 0 # when splitting a window, make sure the new terminal keeps the same # directory, just like gnome-terminal does when opening a new tab bind h send-keys " ~/.scripts/tmux-split -h" \; send-keys "Enter" bind v send-keys " ~/.scripts/tmux-split -v" \; send-keys "Enter" # bind keys for pane synchronizing bind y set-window-option synchronize on bind t set-window-option synchronize off
Normally, when you split the screen, the new created pane takes you to the directory of the tmux server, not the one of the pane you’re currently in. The last two commands fix this by binding two keys to the execution of a script, which I’ve taken from here. The script receives an argument (-h or -v) which tells it what kind of split to do. Then it changes the path of the new pane to your current working directory:
$ cat ~/.scripts/tmux-split #!/usr/bin/env bash PWD=`pwd` tmux split-window $1 tmux send-keys " cd $PWD;clear" tmux send-keys "Enter"
In conclusion…
Tmux is one of those tools which, if configured and used right, can raise your productivity substantially. Even if it’s hard to get used to at first, it’s worth it in the long run.
PS: Even if it hasn’t any practical value, it’s damn cool to have 152 terminals into one single screen :)



