AgentSkillsCN

Tmux

Tmux

SKILL.md

Tmux Remote Control Skill

Purpose

Control tmux sessions programmatically to manage long-running processes, detached workflows, and persistent development environments. This skill enables creating sessions, sending commands to pane/ windows, and monitoring output without interactive terminal access.

Capabilities

  • Create and manage tmux sessions
  • Send commands to specific panes/windows
  • Capture pane output for inspection
  • Run long-lived processes in background
  • Split windows and manage layouts
  • Execute remote commands via SSH + tmux
  • Monitor process status and logs

Dependencies

  • tmux

    bash
    # macOS
    brew install tmux
    
    # Ubuntu/Debian
    sudo apt install tmux
    
    # Arch Linux
    sudo pacman -S tmux
    
    # CentOS/RHEL/Fedora
    sudo dnf install tmux
    
  • (Optional) tmuxinator for project configs

    bash
    gem install tmuxinator
    

Core Concepts

code
Server
 ├── Session "dev"
 │   ├── Window 0: "editor"
 │   │   ├── Pane 0 (vim)
 │   │   └── Pane 1 (terminal)
 │   └── Window 1: "servers"
 │       ├── Pane 0 (npm run dev)
 │       └── Pane 1 (webpack --watch)
 └── Session "deploy"
     └── Window 0: "production"
         └── Pane 0 (ssh ...)

Usage Examples

Session Management

bash
# Create new session
# -d: detached, -s: session name

tmux new-session -d -s mysession

# Create with initial window name
tmux new-session -d -s mysession -n editor

# List all sessions
tmux list-sessions

# Attach to session
tmux attach-session -t mysession

# Kill session
tmux kill-session -t mysession

# Rename session
tmux rename-session -t oldname newname

Window Management

bash
# Create new window in session
tmux new-window -t mysession -n "window-name" -d

# List windows
tmux list-windows -t mysession

# Rename window
tmux rename-window -t mysession:0 "new-name"

# Select window
tmux select-window -t mysession:1

# Kill window
tmux kill-window -t mysession:window-name

Pane Operations

bash
# Split window horizontally (left/right)
tmux split-window -h -t mysession:window

# Split window vertically (top/bottom)
tmux split-window -v -t mysession:window

# List panes
tmux list-panes -t mysession:window

# Select pane
tmux select-pane -t mysession:window.1

# Resize pane
tmux resize-pane -t mysession:window.0 -x 80 -y 24

# Kill pane
tmux kill-pane -t mysession:window.0

Sending Commands (Key Use Case)

bash
# Send keys to a pane (most common for automation)
# -l: literal string

tmux send-keys -t mysession:window.0 "ls -la" Enter
tmux send-keys -t mysession:window.1 "npm run dev" Enter
tmux send-keys -t mysession:window.2 "python server.py" Enter

# Send special keys
tmux send-keys -t mysession:window.0 C-c          # Ctrl+C
tmux send-keys -t mysession:window.0 C-l          # Clear screen
tmux send-keys -t mysession:window.0 Escape       # ESC key

Capturing Output

bash
# Capture pane content to buffer
tmux capture-pane -t mysession:window.0

# Capture with line limits
tmux capture-pane -t mysession:window.0 -S -100     # Last 100 lines

# Save buffer to file
tmux save-buffer /tmp/pane-output.txt

# Capture and save in one go
tmux capture-pane -t mysession:window.0 \; save-buffer /tmp/output.txt

# Show buffer contents
tmux show-buffer

# Clear pane history before capturing
tmux send-keys -t mysession:window.0 C-c \; send-keys -t mysession:window.0 "clear" Enter

Running Long-Lived Processes

bash
# Start a job in detached session
tmux new-session -d -s servers -n "backend"
tmux send-keys -t servers:backend.0 "python manage.py runserver 0.0.0.0:8000" Enter

# Start another service in new window
tmux new-window -t servers -d -n "frontend"
tmux send-keys -t servers:frontend.0 "npm run dev" Enter

# Check if process is running
tmux capture-pane -t servers:backend.0 -p | tail -10

Remote Control Pattern (SSH + tmux)

bash
# Execute command on remote server via tmux
# Useful for: server deployment, remote builds, log monitoring

# SSH and create session remotely
ssh user@server "tmux new-session -d -s deploy -n 'build'"

# Send commands remotely
ssh user@server "tmux send-keys -t deploy:build.0 'cd /app && git pull' Enter"

# Capture output remotely
ssh user@server "tmux capture-pane -t deploy:build.0 -p"

# Kill remote session
ssh user@server "tmux kill-session -t deploy"

Status and Monitoring

bash
# Check session exists (returns 0 if yes)
tmux has-session -t mysession 2>/dev/null && echo "exists"

# Get process status in pane
tmux capture-pane -t mysession:window.0 -p | grep -E "error|Error" || echo "No errors found"

# Wait for process
tmux send-keys -t mysession:window.0 "./long-task.sh" Enter
sleep 5
tmux capture-pane -t mysession:window.0 -p | tail -1

Complete Workflow Examples

Development Environment Setup

bash
#!/bin/bash
# setup-dev.sh - Create full dev environment

SESSION="myproject"

# Kill existing if present
tmux kill-session -t $SESSION 2>/dev/null

# Create base session
tmux new-session -d -s $SESSION -n "editor"

# Editor window
tmux send-keys -t $SESSION:editor.0 "cd ~/projects/myproject && nvim" Enter

# Terminal window with split
tmux new-window -t $SESSION -d -n "terminal"
tmux split-window -h -t $SESSION:terminal
tmux send-keys -t $SESSION:terminal.0 "cd ~/projects/myproject" Enter
tmux send-keys -t $SESSION:terminal.1 "cd ~/projects/myproject && git status" Enter

# Services window
tmux new-window -t $SESSION -d -n "services"
tmux split-window -h -t $SESSION:services
tmux send-keys -t $SESSION:services.0 "npm run dev" Enter
tmux send-keys -t $SESSION:services.1 "docker-compose up" Enter

echo "Session '$SESSION' created. Attach with: tmux attach -t $SESSION"

CI/CD Deployment Monitor

bash
#!/bin/bash
# deploy-and-monitor.sh

SESSION="deploy"
SERVER="prod@example.com"

tmux new-session -d -s $SESSION -n "deploy"

# Run deployment
tmux send-keys -t $SESSION:deploy.0 "ssh $SERVER" Enter
tmux send-keys -t $SESSION:deploy.0 "cd /app && sudo systemctl stop myapp" Enter
tmux send-keys -t $SESSION:deploy.0 "git pull origin main" Enter
tmux send-keys -t $SESSION:deploy.0 "npm install && npm run build" Enter

# Monitor in split panel
tmux send-keys -t $SESSION:deploy.0 "sudo systemctl start myapp && sudo systemctl status myapp" Enter

# Periodic status capture
echo "Deployment started. Monitoring..."
sleep 30

# Check for errors
tmux capture-pane -t $SESSION:deploy.0 -p -S -20 > /tmp/deploy-status.txt
if grep -q "error\|failed\|Error" /tmp/deploy-status.txt; then
    echo "Deployment may have issues! Check /tmp/deploy-status.txt"
else
    echo "Deployment appears successful"
fi

Log Monitoring Setup

bash
#!/bin/bash
# monitor-logs.sh

SESSION="logs"
tmux kill-session -t $SESSION 2>/dev/null

tmux new-session -d -s $SESSION -n "main"

# Four-way split for different logs
tmux split-window -h -t $SESSION:main
tmux split-window -v -t $SESSION:main.0
tmux split-window -v -t $SESSION:main.1

# Start tailing different logs
tmux send-keys -t $SESSION:main.0 "tail -f /var/log/nginx/access.log" Enter
tmux send-keys -t $SESSION:main.1 "tail -f /var/log/nginx/error.log" Enter
tmux send-keys -t $SESSION:main.2 "tail -f /var/log/app/application.log" Enter
tmux send-keys -t $SESSION:main.3 "htop" Enter

echo "Log monitoring session active: tmux attach -t logs"

Configuration

Create ~/.tmux.conf for better experience:

conf
# Mouse support
set -g mouse on

# Vi mode for copy/paste
setw -g mode-keys vi

# Larger scrollback buffer
set -g history-limit 50000

# No delay for escape key
set -sg escape-time 0

# Status bar
set -g status-style bg=black,fg=white
set -g status-left "[#S] "
set -g status-right "%H:%M"

# Pane border colors
set -g pane-border-style fg=black
set -g pane-active-border-style fg=blue

Common Targets Reference

code
tmux <cmd> -t <target>

# Target formats:
session          : mysession
window           : mysession:0, mysession:window-name
pane             : mysession:window.pane_number
                 mysession:window-name.0

# Special:
last             : @ (last window), ; (last pane)
next             : + (next window)
previous         : - (previous window)

Tips

  • Always use -d when creating sessions/windows to stay detached
  • Capture output before and after important steps to verify state
  • Use -l flag with send-keys for literal strings (no key name expansion)
  • Pipe to cat -v when debugging output to see control characters
  • Check session exists with has-session before operations to avoid errors
  • Use ; to chain tmux commands: tmux command1 \; command2

Troubleshooting

bash
# Session already exists error
tmux kill-session -t name 2>/dev/null; tmux new-session -d -s name

# Pane not found - use correct format
tmux list-panes -t session:window  # Verify pane numbers

# Keys not sending properly
# Use quotes: "C-c" not C-c, "Hello World" not Hello World

# Output empty after capture
# Wait a moment: sleep 1; then capture
# Use -S negative number to ensure lines exist

Security Considerations

  • Be careful with send-keys - commands are executed in target pane
  • Don't expose tmux socket to untrusted users
  • Use SSH for remote tmux control, not exposed tmux sockets
  • Clear sensitive output from history when done

Resources