courses

tmux: The Terminal Multiplexer

The tool that saves your work when the connection drops

Picture this: you ssh into the course VM, start a long fuzzing run or a gdb session, and your laptop’s Wi-Fi hiccups. The SSH connection dies, your shell gets a SIGHUP, and everything you were running is gone. tmux is the tool that makes that never happen again — and, as a bonus, lets you split one terminal into many.

A terminal multiplexer does two big things: it persists sessions independently of any connection (detach, disconnect, reconnect later, everything still running), and it multiplexes one terminal into multiple windows and panes. For remote work over SSH it is close to essential, which is why the course setup installs and configures it.

This page covers the theory (what tmux is and its client-server model) and the practice (sessions, windows, panes, copy mode, and config), with the operational payoffs called out along the way.

Theory

From SCREEN to tmux

The idea is old. screen (yes, historically written all-caps) pioneered persistent, detachable terminal sessions in the 1980s. tmux is the modern successor: same core idea, but a cleaner client-server design, easier configuration, vertical and horizontal splits, and a scripting interface. Both use a chorded interface — a prefix key combination puts tmux into command mode, then a follow-up key performs an action (the same interaction model as Emacs and VS Code; vim, by contrast, is modal).

The client-server model

This is the key mental model and the source of tmux’s power. tmux is not one program but two roles:

So “closing the window” doesn’t kill your work; it just detaches a client. The server, and everything in it, keeps humming until you explicitly kill it or the machine reboots.

The session / window / pane hierarchy

tmux organizes terminals in three nested levels — learn this vocabulary and the keybindings make sense:

session            ← a named workspace (e.g. "labwork"); survives disconnects
└── window         ← like a tab; one full screen, has a number and name
    └── pane       ← a split of a window; each pane is one shell/program

So you might keep one session per project, with a window for editing, a window split into panes for a program and its debugger, and another window watching logs — all persistent.

Practice

The prefix key

Every tmux command starts with the prefix, by default Ctrl+b (written C-b). Press the prefix, release, then press the command key. Many people rebind the prefix to Ctrl+a (easier to reach, the old screen binding) in their config.

In the tables below, C-b means “press the prefix,” and the second key is the command.

Sessions — the persistence layer

From the shell:

tmux                          # start a new unnamed session
tmux new -s labwork           # start a new NAMED session 'labwork'
tmux ls                       # list running sessions (on the server)
tmux attach -t labwork        # re-attach to a session
tmux attach                   # attach to the most recent session
tmux kill-session -t labwork  # end a session
Prefix key Action
C-b d Detach — leave the session running, return to your shell (the killer feature)
C-b s Interactive list of sessions to switch to
C-b $ Rename the current session

The persistence workflow over SSH: ssh server, tmux new -s work, do things, C-b d to detach (or just lose the connection), and later ssh server; tmux attach -t work — exactly where you left off. This is the process-persistence story done right, far better than nohup/disown for interactive work.

Windows — like tabs

Prefix key Action
C-b c Create a new window
C-b n / C-b p Next / previous window
C-b 09 Jump to window by number
C-b , Rename the current window
C-b w Interactive window/session tree
C-b & Kill the current window

Panes — splitting one screen

By default C-b % splits left/right and C-b " splits top/bottom (unintuitive, so many configs rebind these to | and -).

Prefix key Action
C-b % Split pane left/right (vertical divider)
C-b " Split pane top/bottom (horizontal divider)
C-b + arrow Move focus between panes
C-b o Cycle to the next pane
C-b z Zoom — toggle the current pane to full screen and back
C-b x Kill the current pane
C-b { / C-b } Swap pane position
C-b + C-arrow Resize the current pane
C-b Space Cycle through preset layouts

A common debugging layout: source/editor in one pane, the program in a second, and gdb/pwndbg in a third — all visible at once, all in one SSH session.

Copy mode and scrollback

The terminal’s own scrollback doesn’t work normally inside tmux; instead you enter copy mode to scroll, search, and select:

C-b [        enter copy mode (then PgUp/PgDn/arrows to scroll)
C-b ]        paste the copied buffer

In copy mode you can search the scrollback (/ forward, ? back with vi keys) and select text to copy into a tmux buffer. Setting setw -g mode-keys vi makes copy-mode navigation use vi bindings.

Configuration: ~/.tmux.conf

tmux is configured in ~/.tmux.conf. A sensible starter:

# Rebind prefix to Ctrl-a (easier than Ctrl-b)
unbind C-b
set -g prefix C-a
bind C-a send-prefix

# Intuitive split bindings, opening in the current directory
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"

set -g mouse on              # mouse: select panes, resize, scroll
setw -g mode-keys vi         # vi keys in copy mode
set -g base-index 1          # number windows from 1, not 0
set -g history-limit 50000   # bigger scrollback

# Reload config without restarting tmux
bind r source-file ~/.tmux.conf \; display "reloaded"

Reload a changed config from inside tmux with C-b :source-file ~/.tmux.conf (or the C-b r binding above).

Plugins and scripted layouts

The tmux Plugin Manager (tpm) manages plugins; popular ones add a richer status bar (powerline), and tmux-resurrect/tmux-continuum save and restore entire session layouts across reboots. For repeatable layouts, tmuxinator describes a session (windows, panes, commands) in a YAML file so a single command rebuilds your whole working environment.

ℹ️ Because the tmux server is just a process, you can drive it by script: tmux send-keys -t work:0 "make test" Enter types into a pane from outside, and tmux new-session -d starts a detached session. This is how dashboards and automated lab setups are built.

Why it matters here

Key takeaways

References


Related course pages: SSH: Secure Shell · Process Management · Software Configuration · zsh: The Z Shell · Memory Corruption · Shell and Other Basics

🛠️ Maintenance note: tmux keybindings and config syntax are stable, but the config format changed at tmux 3.x in a few places (set -g option names, bind -n), so older ~/.tmux.conf snippets online may not load cleanly — verify against the tmux version on the course VM (tmux -V).