Tmux as a ClusterSSH alternative
Date: 2024-Jun-28
A neat feature of tmux is that is supports multi-pane synchronized input via the set-option synchronize-panes 1
command. This allows you to enter input across all panes simultaneously.
While there are other tmux cluster bash scripts, they focus on trying to replicate ClusterSSH closely instead of being a generic 'open tmux with this many panes and this command.' script. Sometimes you want to sync other things than just ssh. One useful task I used the x11 based ClusterSSH for was opening several ssh to localhost windows and opening a seperate JSON log file in each. This was very handy for debugging having scroll synced across each file. Tmux makes this easier and now with the script below it's as simple as calling it with the commands you want for each pane. Plus it no longer needs an x11 terminal. So using it on a wayland only setup or even over ssh works well too.
Below is a small bash script and some examples showing how you can use synchronized input on tmux, including commands to disable input on certain panes, plus running nested tmux.
Key features of script:
- Sets tmux up to auto tile and synchronizes N panes on single window.
- Changed default tmux prefix from: CTRL + b to: ALT + b for when nesting tmux. eg: ssh
- Can rename session name via
TCS_SESSION_NAME
environment variable or keep the default name of tcs_<PROCESS_ID>
Some useful tmux commands, Prefix: followed by command:
set-option synchronize-panes 1
to enable sync mode for entire window.set-option synchronize-panes 0
to disable sync mode for entire window.select-pane -e
to enable input for the active pane leaving others untouched.select-pane -d
to disable input for the active pane leaving others untouched.
Script saved as: tcs.sh
- Tmux Clustered Session. (Can also add script to $PATH
)
Usage and examples:
./tcs.sh 1 2 3
Open tmux with 3 tiled panes, with the number typed into each pane respectively../tcs.sh 1 2 "3 4"
3 tiled panes 3rd pane has longer cmd.TCS_SESSION_NAME=Custom_name ./tcs.sh 1 2 3
Set a custom name for session../tcs.sh "ssh -p 1234 10.0.0.1" "ssh -p 1234 10.0.0.2"
2 panes with ssh commands.
Images:
Code:
#!/bin/bash
# SPDX-License-Identifier: MPL-2.0 OR Unlicense
# Version: 0.1.0
# Halt on errors.
set -o errexit # Abort on nonzero exitstatus.
set -o nounset # Abort on unbound variable.
set -o pipefail # Don't hide errors within pipes.
# Name of tmux session from env var or default: (tcs_<processID>)
session="${TCS_SESSION_NAME:=tcs_$$}"
# Create new tmux session (detached) with custom name.
tmux new-session -d -s "${session}"
# Change default prefix from Ctrl-b to Alt-b (For nested tmux).
tmux set-option -t "${session}" prefix M-b
# Select the first window and pane just to be sure.
tmux select-pane -t "${session}":0.0
# To skip first split as tmux has a pane open by default.
declare -i i=0
# Split window and type cmd.
for cmd in "${@}"; do
if [[ "${i}" -ne 0 ]]; then
# Split window to create a pane for -1 each cmdline args.
# Change the layout to be tiled after each split.
# If the pane is too small tmux will fail to split.
tmux split-window -t "${session}"
tmux select-layout -t "${session}" tiled
fi
# Type cmd into each pane.
tmux send-keys -t "${session}":0."${i}" "${cmd}"
# Increment & ignore status code.
(( i++ )) || true
done
# Select first window and pane to start.
tmux select-pane -t "${session}":0.0
# Set panes to start synchronized.
tmux set-option -t "${session}" synchronize-panes 1
# Attach to the newly created session.
tmux attach -t "${session}"