| name | tmux |
| description | Expert tmux session, window, and pane management for terminal multiplexing, persistent remote workflows, and shell scripting automation. |
| category | development |
| risk | safe |
| source | community |
| date_added | 2026-03-28 |
| author | kostakost2 |
| tags | ["tmux","terminal","multiplexer","sessions","shell","remote","automation"] |
| tools | ["claude","cursor","gemini"] |
tmux — Terminal Multiplexer
Overview
tmux keeps terminal sessions alive across SSH disconnects, splits work across multiple panes, and enables fully scriptable terminal automation. This skill covers session management, window/pane layout, keybinding patterns, and using tmux non-interactively from shell scripts — essential for remote servers, long-running jobs, and automated workflows.
When to Use This Skill
- Use when setting up or managing persistent terminal sessions on remote servers
- Use when the user needs to run long-running processes that survive SSH disconnects
- Use when scripting multi-pane terminal layouts (e.g., logs + shell + editor)
- Use when automating
tmux commands from bash scripts without user interaction
How It Works
tmux has three hierarchy levels: sessions (top level, survives disconnects), windows (tabs within a session), and panes (splits within a window). Everything is controllable from outside via tmux <command> or from inside via the prefix key (Ctrl-b by default).
Session Management
tmux new-session -s work
tmux new-session -d -s work
tmux new-session -d -s build -x 220 -y 50 "make all"
tmux attach -t work
tmux attach
tmux list-sessions
tmux ls
tmux kill-session -t work
tmux kill-session -a
tmux rename-session -t old-name new-name
tmux switch-client -t other-session
tmux has-session -t work 2>/dev/null && echo "exists"
Window Management
tmux new-window -t work -n "logs"
tmux new-window -t work:3 -n "server" "python -m http.server 8080"
tmux list-windows -t work
tmux select-window -t work:logs
tmux select-window -t work:2
tmux rename-window -t work:2 "editor"
tmux kill-window -t work:logs
tmux move-window -s work:3 -t work:1
Pane Management
tmux split-window -h -t work:1
tmux split-window -v -t work:1
tmux split-window -h -t work:1 "tail -f /var/log/syslog"
tmux select-pane -t work:1.0
tmux resize-pane -t work:1.0 -R 20
tmux resize-pane -t work:1.0 -D 10
tmux resize-pane -Z
tmux swap-pane -s work:1.0 -t work:1.1
tmux kill-pane -t work:1.1
Sending Commands to Panes Without Being Attached
tmux send-keys -t work:1.0 "ls -la" Enter
tmux send-keys -t work:editor "vim src/main.py" Enter
tmux send-keys -t work:1.0 C-c
tmux send-keys -t work:1.0 "git commit -m '"
tmux send-keys -t work:1.0 "clear" Enter
tmux capture-pane -t work:1.0 -p
tmux capture-pane -t work:1.0 -p | grep "ERROR"
Scripting a Full Workspace Layout
This is the most powerful pattern: create a fully configured multi-pane workspace from a single script.
#!/usr/bin/env bash
set -euo pipefail
SESSION="dev"
tmux has-session -t "$SESSION" 2>/dev/null && {
echo "Session $SESSION already exists. Attaching..."
tmux attach -t "$SESSION"
exit 0
}
tmux new-session -d -s "$SESSION" -n "editor" -x 220 -y 50
tmux send-keys -t "$SESSION:editor" "vim ." Enter
tmux split-window -h -t "$SESSION:editor"
tmux send-keys -t "$SESSION:editor.1" "npm test -- --watch" Enter
tmux select-pane -t "$SESSION:editor.0"
tmux new-window -t "$SESSION" -n "server"
tmux send-keys -t "$SESSION:server" "docker compose up" Enter
tmux split-window -v -t "$SESSION:server"
tmux send-keys -t "$SESSION:server.1" "tail -f logs/app.log" Enter
tmux new-window -t "$SESSION" -n "shell"
tmux select-window -t "$SESSION:editor"
tmux attach -t "$SESSION"
Configuration (~/.tmux.conf)
unbind C-b
set -g prefix C-a
bind C-a send-prefix
set -g mouse on
set -g base-index 1
setw -g pane-base-index 1
set -g renumber-windows on
set -g history-limit 50000
setw -g mode-keys vi
set -s escape-time 0
bind r source-file ~/.tmux.conf \; display "Config reloaded"
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
bind c new-window -c "#{pane_current_path}"
set -g status-right "#{session_name} | %H:%M %d-%b"
set -g status-interval 5
Copy Mode and Scrollback
tmux list-buffers
tmux show-buffer
tmux save-buffer /tmp/tmux-output.txt
tmux load-buffer /tmp/data.txt
tmux pipe-pane -t work:1.0 "cat >> ~/session.log"
Practical Automation Patterns
ensure_session() {
local name="$1"
tmux has-session -t "$name" 2>/dev/null \
|| tmux new-session -d -s "$name"
tmux attach -t "$name"
}
run_bg() {
local session="${1:-main}" cmd="${*:2}"
tmux new-window -t "$session" -n "bg-$$"
tmux send-keys -t "$session:bg-$$" "$cmd" Enter
}
wait_for_output() {
local target="$1" pattern="$2" timeout="${3:-30}"
local elapsed=0
while (( elapsed < timeout )); do
tmux capture-pane -t "$target" -p | grep -q "$pattern" && return 0
sleep 1
(( elapsed++ ))
done
return 1
}
kill_bg_windows() {
local session="$1" prefix="${2:-bg-}"
tmux list-windows -t "$session" -F "#W" \
| grep "^${prefix}" \
| while read -r win; do
tmux kill-window -t "${session}:${win}"
done
}
Remote and SSH Workflows
ssh user@host -t "tmux attach -t work || tmux new-session -s work"
ssh user@host "tmux new-session -d -s deploy 'bash /opt/deploy.sh'"
ssh user@host -t "tmux attach -t deploy -r"
tmux new-session -s shared
tmux attach -t shared
Best Practices
- Always name sessions (
-s name) in scripts — unnamed sessions are hard to target reliably
- Use
tmux has-session -t name 2>/dev/null before creating to make scripts idempotent
- Set
-x and -y when creating detached sessions to give panes a proper size for commands that check terminal dimensions
- Use
send-keys ... Enter for automation rather than piping stdin — it works even when the target pane is running an interactive program
- Keep
~/.tmux.conf in version control for reproducibility across machines
- Prefer
bind -n for bindings that don't need the prefix, but only for keys that don't conflict with application shortcuts
Security & Safety Notes
send-keys executes commands in a pane without confirmation — verify the target (-t session:window.pane) before use in scripts to avoid sending keystrokes to the wrong pane
- Read-only attach (
-r) is appropriate when sharing sessions with others to prevent accidental input
- Avoid storing secrets in tmux window/pane titles or environment variables exported into sessions on shared machines
Common Pitfalls
-
Problem: tmux commands from a script fail with "no server running"
Solution: Start the server first with tmux start-server, or create a detached session before running other commands.
-
Problem: Pane size is 0x0 when creating a detached session
Solution: Pass explicit dimensions: tmux new-session -d -s name -x 200 -y 50.
-
Problem: send-keys types the text but doesn't run the command
Solution: Ensure you pass Enter (capital E) as a second argument: tmux send-keys -t target "cmd" Enter.
-
Problem: Script creates a duplicate session each run
Solution: Guard with tmux has-session -t name 2>/dev/null || tmux new-session -d -s name.
-
Problem: Copy-mode selection doesn't work as expected
Solution: Confirm mode-keys vi or mode-keys emacs is set to match your preference in ~/.tmux.conf.
Related Skills
@bash-pro — Writing the shell scripts that orchestrate tmux sessions
@bash-linux — General Linux terminal patterns used inside tmux panes
@ssh — Combining tmux with SSH for persistent remote workflows
Limitations
- Use this skill only when the task clearly matches the scope described above.
- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.
- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.