Get Started With Tmux
To Tmux or Not to Tmux, That Is the Question!
Before getting started with tmux, let us go over some questions to see if tmux is right for you:
- Do you use a terminal as part of your your development workflow?
- Do you use multiple terminals in different tabs or windows to navigate files, edit text, compile and run code, tail log files, push code to repository, and run one-time adhoc commands?
- Do you work on multiple projects at a time, each with its own set of workflow and environment requirements, and often have to switch context?
- Do you SSH into remote systems?
- Have you ever got disconnected from a remote SSH session in the middle of a task that you were running and monitoring?
If you answered yes to any of these questions, then tmux is for you!
What Is Tmux?
Tmux is a terminal multiplexer. You can run multiple terminal programs inside tmux, all of which can be accessed from the single terminal that is running tmux. This is called a tmux session. You can have multiple such tmux sessions, say one for each project you are working on. You can detach from a tmux session and later reattach to it. When you run programs in a tmux session, the session remains intact and continues running your programs even if you detach from the session. You can start where you left off the previous day, or you can even access the session from a different computer.
If you have worked with remote servers using remote desktop connection, you will be familiar with how the applications that you open in the server are kept as is even when you disconnect. You can then resume the session by reconnecting to it. You can even reconnect to the remote desktop using a different client or a different computer. Tmux helps you to achieve similar results for terminal sessions.
When you run the tmux
command, tmux starts a server process
if it is not already running, and a tmux session is created. The tmux
server runs as a background process in your system and manages all the
terminals running inside tmux. You can create additional sessions in the
tmux server if needed by using the tmux
command. A tmux
session is a group of related tmux windows. Think of all the terminal
tabs you open to get to your development workflow of a particular
project. All these can be grouped together as windows in a tmux session.
A tmux window comprises of one or more panes. Each pane is like a
terminal by itself. Panes can be organized vertically, horizonatally, or
a mix of both. Think of editing, compiling, and executing code on the
left pane while tailing a related log file on the right pane as an
example. At any given time, there is one active pane where the commands
you type are accepted. You can switch between panes, windows, and
sessions as needed.
Let us now see how to get started with tmux.
Install Tmux
If you are on a Debian, Ubuntu, or another Debian-based system, enter the following command:
sudo apt-get install tmux
If you are on macOS with Homebrew installed, enter the following command:
brew install tmux
If you are on any other system or environment, see Tmux Wiki: Installing for installation details.
Create, Detach From, and Attach to Sessions
To create a new tmux session, enter the following command:
tmux
Run some program in this session. Maybe tail a log file. This will help with the next steps where you detach and reattach to a session.
To detach your terminal from a tmux session, enter the following command:
tmux detach
Tmux will keep your session intact. All your programs keep running on the server. To attach your terminal as a client back to an existing tmux session, enter the following command:
tmux attach
Note that it is not necessary to type out the tmux
commands
in full. You can use any unambiguous abbreviation of the commands. For
example, tmux det
and tmux at
are equivalent
to tmux detach
and tmux attach
, respectively.
By default, the new sessions are named 0, 1 and so on. To choose another name for the session, use the following command to start a new session:
tmux new -s <session-name>
Here <session-name>
denotes the name of the session
you choose. You can also rename an existing session with this command:
tmux rename <new-name>
If you have multiple tmux sessions running and you want to target a
specific session to rename, you can use the -t
option to
specify the session name you want to target, like this:
tmux rename -t <session-name> <new-name>
Without the -t
option, it renames the current session.
The -t
option is useful for attaching to a specific tmux
session too when multiple tmux sessions are running. By default
tmux attach
attaches to the most recently used session that
is not attached. You can attach to a specific session like this:
tmux attach -t <session-name>
Sometimes while attaching to a tmux session, you might want to detach the other clients to connected to it. That can be achieved with the following commands:
tmux attach -d
tmux attach -d -t <session-name>
While you are inside a tmux session, you can also change the name of the
attached session by using the key-sequence C-b $
which
prompts for a new name for the session. The key-sequence C-b
$
is bound to the rename
command that you saw above.
Similarly, the key-sequence C-b d
is bound to the
detach
command. To understand how tmux key bindings and
commands work together, read the next two sections.
Understand Tmux Prefix Keys
Once you attach your terminal as a client to a tmux session, all
keystrokes are sent to the program running in the active pane of the
current tmux window. By default it is your shell. For key-sequences that
control tmux itself, a special key-sequence called the prefix key must
be pressed. By default the prefix key is C-b
. Here
C
denotes the Ctrl
modifier key, i.e., to
enter C-b
, press and hold the Ctrl
key, then
press and release the b
key, and finally release the
Ctrl
key. When the prefix key is entered like this, tmux
waits for another keystroke or key-sequence to determine which tmux
command needs to be executed. For example, when you enter C-b
$
to rename the current session, C-b
is the prefix
key that tells tmux that you are going to invoke a tmux command and then
the $
keystroke tells tmux that you want to invoke the tmux
rename
command.
Key Bindings, Commands, and Command Prompt
The key-sequence C-b ?
shows the list of key bindings along
with short descriptions about what they do. The output is shown in the
view mode in the active pane. The pane in view mode has its own key
bindings which don't need the prefix key. By default the view mode has
Emacs key bindings that you can use to navigate the output. However, it
can be configured to use vi key bindings too.
Any time key bindings are used, they run the underlying tmux commands.
For example C-b c
runs the neww
command that
creates a new window. Commands can be run directly from the shell as you
saw when you created new session using the tmux new
command. Just like any other Unix commands, tmux commands have zero or
more command line options that may or may not accept arguments. For
example, the attach
command that you saw earlier accepts
the -d
option to detach any other clients that are attached
to the session. This option does not require an argument. The
attach
command also accepts another option -t
that requires an argument to specify the name of the target session you
want to attach to.
You might mostly want to use the key bindings to manipulate tmux because they are convenient. However, the tmux commands can be useful especially when you want to perform a task that is supported only by an option. The tmux commands are also useful if you want to write a script to manipulate tmux.
Tmux commands can be run from the shell as you have seen so far. There
is also an interactive command prompt available within tmux that you can
open using C-b :
. This prompt accepts tmux commands. For
example, C-b :neww
creates a new window in the attached
session. Some of the tmux commands run in this manner show the output in
the view mode in the active pane. For example, C-b :ls
shows the list of all available sessions.
Create New Windows in a Session and Switch Between Them
You can create new window in a session by using C-b c
or
C-b :neww
. Each window is numbered starting from 0. Every
new window is created at the first available index. This means that if
there are gaps in the list of window numbers, a new window occupies the
first available number in the gaps. The new window thus created becomes
the current window of the session. The current window is identified by
the *
suffix in its name and the previous window is
identified by the -
suffix in its name.
If you want to create a new window but not make it the current window,
you can do so with the -d
option like this: C-b :neww
-d
. You can also create a window at a specific index by using the
-t
option like this: C-b :neww -t 9
.
C-b 0
takes you to window 0, C-b 1
takes you
to window 1, and so on until C-b 9
. C-b '
prompts for an index to switch to that window. This can be useful if you
want to go to windows with indices greater than 9. C-b p
takes you to the previous window and C-b n
takes you to the
next window in the window list by index. C-b l
takes you to
the last window that was active before the current one. This is very
useful for alternating between two windows again and again.
To rename the current window, you can use C-b :renamew
<new-name>
or C-b ,
which prompts for the
new name for the window.
I find it convenient not to exceed 10 windows (indices 0-9) in a
session, so that I can switch between them using C-b
<number>
.
Create New Panes in a Window and Switch Between Them
You can create a new pane by splitting a pane in a window. C-b
%
splits the current pane into left and right panes. C-b
"
splits the current pane into top and bottom panes. These
new panes can be split again and again recursively.
C-b o
takes you to the next pane by number. You can use
C-b <Up>
, C-b <Down>
, C-b
<Left>
, or C-b <Right>
to go to the pane
above, below, left, or right, respectively, of the active pane. These
keys wrap around the window, so to get to the left most pane from the
right most pane, you can press C-b <Right>
.
List Sessions and Switch Between Them
You can see a list of available sessions by executing the following command on the shell:
tmux ls
You can then attach to the session you are interested in. Another way to
do this is inside tmux using the tree mode. You can use the key sequence
C-b s
or enter C-b :ls
to go to the tree mode
that shows the list of sessions with the attached session selected. Keys
to control tree mode do not need prefix keys. The list of sessions can
be navigated using the <Up>
and
<Down>
keys. The Emacs key bindings C-p
and C-n
work too. If vi key bindings are configured then
j
and k
work too. Press the space
bar to expand or collapse the list of windows under each session. Press
the enter
key to go to a session or window.
Configure Tmux
You can configure tmux by defining the configuration in a file called
.tmux.conf
in your home directory. This configuration comes
into effect when the tmux server is first started. When you modify this
configuration, be sure to restart your tmux server. A graceful way to do
so is to quit all windows and sessions, and then start a new tmux
session. A quick and dirty way to do so is with the following commands:
tmux kill-server tmux
Let us see some of the useful lines of configuration that can go into
~/.tmux.conf
.
-
Set
C-j
as the secondary prefix key.set -g prefix2 C-j
This allows you to control tmux with
C-j
in addition toC-b
. I findC-j
to be a more convenient prefix key because thej
key exists in the home row of the keyboard right under the index finger. -
Send the secondary prefix key to a window, i.e., send
C-j
whenC-j C-j
is pressed.bind-key C-j send-prefix -2
This allows you to send
C-j
to a program running within tmux. -
Customize kill key-sequences such that they do not ask for confirmation.
bind-key & kill-window bind-key x kill-pane
The key binding
C-b &
kills the current window and the key bindingC-b x
kills the current pane. However, without the configuration specified above, you will be prompted to confirm the operation with ay
orn
. For example:C-b x
in pane number 2, will prompt you withkill-pane 2? (y/n)
. It is convenient to be able to kill a window or a pane without having to go through a confirmation prompt. -
Open a new pane or window with the current directory of the current pane, not the directory in which the first tmux session was started.
bind '"' split-window -c "#{pane_current_path}" bind % split-window -h -c "#{pane_current_path}" bind c new-window -c "#{pane_current_path}"
Here the
-c
option is used to specify the start directory for the new pane. The current path is represented with the replacement variablepane_current_path
in the commands above. The-h
option specifies that the window should be split into left and right panes. -
Use 256 colors in tmux.
set -g default-terminal screen-256color
By default tmux sets the
TERM
environment variable toscreen
. With this setting, most programs will support 8 colors only. For example, Vim syntax highlighting will use 8 colors only. To configure tmux to set the terminal to use 256 colors, set theTERM
environment variable toscreen-256color
.With this configuration, programs that use colors can make use of all 256 colors. Here is a quick shell command to test how the 256 look in the terminal:
for i in {0..255}; do tput setaf $i; printf "$i "; done
-
Use vi key bindings in tmux.
set -g mode-keys vi
By default, tmux uses Emacs key bindings in various modes, e.g., view-mode, tree-mode, etc. If you use Vim instead of Emacs, it is convenient to set vi key bindings.
I have made my tmux configuration available at https://github.com/sunainapai/dotfiles/blob/master/tmux.conf.