References¶
- https://github.com/tmux/tmux
- https://opensource.com/article/20/7/tmux-cheat-sheet
man tmux— exhaustive, worth skimming once for the config file directives
1. Core mental model¶
tmux is a client/server architecture: tmux starts (or attaches to) a server process that owns one or more sessions. Each session holds windows (like tabs), each window holds one or more panes (splits). Detaching a session doesn't kill it — the server keeps running in the background, which is the entire point: start a long job over SSH, detach, close your laptop, reattach from anywhere later and the job is still running and the scrollback is intact.
All tmux commands are triggered by a prefix key (default Ctrl+b) followed by a command key. You press the prefix, release it, then press the command key — they are not held simultaneously.
2. Your notes, expanded¶
List and attach to sessions¶
tmux ls
tmux attach-session -t [session_id]
tmux a -t [session_id] # 'a' is the short alias for attach-session
If you don't remember the exact name, tmux ls first — session names/numbers are shown with their window count and last-attached time, which is often enough to identify the right one.
Detach¶
Ctrl+b, release, d
The session keeps running with everything inside it exactly as it was — nothing is killed, this is the whole value proposition over a plain SSH session.
Log stdout from inside a session¶
tmux pipe-pane 'cat >> ~/overcloud_scaleout.log'
pipe-pane pipes the pane's output to a shell command — here just appending to a file. Run it again with no argument to stop piping:
tmux pipe-pane # toggles off logging on the current pane
Cleaner alternative if you just want a plain-text transcript of everything: tmux pipe-pane -o 'cat >> pane.log' (-o only captures output generated after the pipe starts, avoiding a scrollback dump).
Split window¶
Ctrl+b, Shift+" (splits horizontally — new pane below)
Ctrl+b, Shift+% (splits vertically — new pane to the right)
3. Sessions, windows, panes — full command reference¶
Sessions¶
tmux new -s mysession # start a new named session
tmux new -s mysession -d # start it detached (great for scripting/automation)
tmux kill-session -t mysession
tmux rename-session -t old new
tmux switch-client -t mysession # switch to a different session from inside tmux
Inside tmux (prefix Ctrl+b then):
| Key | Action |
|---|---|
| d | detach |
| s | list & choose sessions interactively |
| $ | rename current session |
| ( / ) | switch to previous/next session |
Windows (tabs)¶
| Key (after prefix) | Action |
|---|---|
c |
create new window |
, |
rename current window |
w |
list windows interactively |
n / p |
next / previous window |
0–9 |
jump directly to window number |
& |
kill current window |
f |
find a window by searching pane content |
Panes (splits)¶
| Key (after prefix) | Action |
|---|---|
" |
split horizontally (new pane below) |
% |
split vertically (new pane to the right) |
| arrow keys | move focus between panes |
o |
cycle focus to next pane |
z |
toggle pane zoom (fullscreen the focused pane temporarily) |
x |
kill current pane |
{ / } |
swap pane position with previous/next |
Ctrl+arrow (with resize repeat) |
resize the focused pane |
Space |
cycle through predefined pane layouts |
! |
break the current pane out into its own window |
4. Copy mode (tmux's scrollback / clipboard)¶
Ctrl+b [ # enter copy mode (scroll with arrows/PageUp, vi or emacs keybindings depending on config)
Space # (vi mode) start selection
Enter # (vi mode) copy selection to tmux's paste buffer
Ctrl+b ] # paste the most recent buffer
Ctrl+b = # choose from multiple saved paste buffers
Set set -g mode-keys vi in .tmux.conf to get vi-style navigation/selection in copy mode — the default emacs bindings are far less ergonomic for anyone used to vi.
5. .tmux.conf — worth actually customizing¶
A few config lines that pay for themselves immediately:
set -g mouse on # click to select panes, drag to resize, scroll wheel for scrollback
set -g history-limit 50000 # scrollback buffer size (default is often only 2000 lines)
set -g base-index 1 # windows numbered from 1, not 0 (matches keyboard layout better)
setw -g mode-keys vi # vi keys in copy mode
set -g status-interval 5 # refresh status bar every 5s (for date/battery/etc widgets)
bind r source-file ~/.tmux.conf \; display "Reloaded!" # quick reload binding
6. Scripting / automating tmux itself¶
Because the client/server split means every action has a CLI equivalent, you can fully script a working environment:
tmux new-session -d -s work -n editor
tmux send-keys -t work:editor 'vim' C-m
tmux split-window -t work:editor -h
tmux send-keys -t work:editor.1 'htop' C-m
tmux new-window -t work -n logs
tmux send-keys -t work:logs 'tail -f /var/log/syslog' C-m
tmux attach -t work
This is the pattern behind tools like tmuxinator/tmuxp (YAML-defined session layouts) — worth adopting for any recurring multi-pane workflow (e.g. a standard "deploy + logs + shell" layout you spin up daily).
7. Nesting tmux over SSH (and the prefix collision problem)¶
If you ssh from inside a local tmux session into a remote box that also runs tmux, both instances fight over Ctrl+b. Fixes:
- Rebind the remote tmux's prefix (e.g. Ctrl+a) in the remote .tmux.conf.
- Or send the prefix through explicitly: Ctrl+b Ctrl+b <command-key> sends a literal prefix keystroke to the inner session.
8. Recording terminal sessions¶
Distinct from tmux's own pipe-pane logging, these tools capture a full replayable terminal session (timing included), useful for demos, audit trails, or documenting an incident.
script — universal, always available¶
script -q session.log # start recording (types, output, everything) to session.log
exit # or Ctrl+d — stops recording
script -T timing.log -q session.log # also record timing data, needed for accurate playback speed
scriptreplay -t timing.log session.log # replay at original speed
script is POSIX/coreutils-adjacent and present on essentially every Linux/BSD box with zero install — the fallback when nothing else is available.
asciinema — the modern standard for shareable recordings¶
asciinema rec demo.cast # record
asciinema play demo.cast # replay locally
asciinema upload demo.cast # push to asciinema.org for a shareable link/embed
asciinema rec --idle-time-limit 2 demo.cast # cap long pauses so playback isn't full of dead air
Output is a lightweight JSON-based .cast file (text, not a video) — tiny file size, embeds cleanly on a docs/blog site (relevant for andrewmercer.net) via the asciinema player JS widget, and is trivially copy-pasteable as text if someone needs to extract commands from it later. This is generally the better choice over script for anything you intend to actually publish or share.
ttyrec / ttygif — record + convert to GIF¶
ttyrec session.ttyrec
# ... do stuff, then exit
ttygif session.ttyrec # produces an animated GIF, good for READMEs where a JS player isn't an option
tmux itself, for lightweight always-on capture¶
Since you already have tmux running, pipe-pane (see §2) is the zero-extra-tooling way to keep a rolling plaintext transcript of a pane — not a true "replay," but often all you need for post-mortem/audit purposes:
tmux pipe-pane -o 'cat >> ~/logs/pane-$(date +%F).log'
Recommendation¶
- Quick one-off, nothing to install:
script - Something you'll publish/embed/share (blog post, docs page, PR description):
asciinema - Continuous background audit trail of a long-running pane:
tmux pipe-pane - Need a GIF for a platform with no JS player support:
ttyrec→ttygif, orasciinema→agg(asciinema's newer GIF-generator CLI, faster than ttygif)
9. Quick cheat sheet¶
tmux new -s name # new named session
tmux ls # list sessions
tmux a -t name # attach
Ctrl+b d # detach
Ctrl+b c # new window
Ctrl+b " / % # split horiz / vert
Ctrl+b arrow # move between panes
Ctrl+b z # zoom pane
Ctrl+b [ # copy mode
Ctrl+b ] # paste
tmux pipe-pane 'cat >> f.log' # log pane output
asciinema rec demo.cast # record a shareable session