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
- •
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
bashgem 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
-dwhen creating sessions/windows to stay detached - •Capture output before and after important steps to verify state
- •Use
-lflag with send-keys for literal strings (no key name expansion) - •Pipe to
cat -vwhen debugging output to see control characters - •Check session exists with
has-sessionbefore 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