Skip to content

Instantly share code, notes, and snippets.

@jontow
Last active March 25, 2020 21:01
Show Gist options
  • Save jontow/600a70cf6e59264488aa0f4c8cea473c to your computer and use it in GitHub Desktop.
Save jontow/600a70cf6e59264488aa0f4c8cea473c to your computer and use it in GitHub Desktop.
tmux-sync-split.sh (tss) script, spawn synchronized tmux panes with ssh or custom command
#!/bin/sh
################################################################################
#
# 2020-03-17 -- [email protected]
#
# Start a new synchronized 'N'-pane tmux session and run "$TSS_CMD $host" in
# each of the split window panes.
#
################################################################################
#
# Override variables:
#
# TSS_CMD: run custom command in each pane, instead of 'ssh': supplies each
# pane with a hostname from input list, unless.. (see: TSS_NOHOST)
#
# TSS_LAYOUT: use some other predefined tmux layout, see tmux(1) manpage
# for details (search "select-layout"), but common options are:
# even-vertical, even-horizontal, tiled, main-vertical, main-horizontal
#
# TSS_NOHOST: if set to any non-empty value, prevents input hosts from being
# supplied as parameters to TSS_CMD: this parameter is useless without
# also supplying some custom TSS_CMD.
#
################################################################################
#
# Other notes:
#
# Panes will remain in place after processes exit to collect output.
#
# Key bindings set by this script:
#
# k kill-session
# = toggle synchronize-panes
#
# Easiest way to exit after all panes are dead:
# tmux escape char, then k
# example: ^bk
#
################################################################################
#
# EXAMPLES
#
########################################
#
# Override TSS_CMD in your shell (for testing or otherwise) like so:
#
# TSS_CMD=echo ./tmux-sync-split host1 host2 host3
#
# Override TSS_LAYOUT if you need/want tiled or horizontal splits like this:
#
# TSS_LAYOUT=tiled ./tmux-sync-split host1 host2 host3
#
########################################
#
# Setup a 4-pane interactive shell 'dashboard'. Can immediately turn off
# synchronize-panes and move between to run commands on local host. Try
# using main-vertical or another predefined layout here as you prefer:
#
# TSS_NOHOST=true TSS_LAYOUT=main-horizontal TSS_CMD=/bin/bash tss $(seq 1 3)
#
########################################
# Nightmare fuel test case:
#
# Spawn a 3x3 grid of synchronized panes running interactive local shell (bash);
# synchronization can be toggled for either rows or columns, and easy to get in
# a very awkward sync state:
#
# TSS_NOHOST=true TSS_LAYOUT=even-horizontal TSS_CMD="TSS_NOHOST=true \
# TSS_LAYOUT=even-vertical TSS_CMD=/bin/bash TMUX= tss 4 5 6" tss 1 2 3
#
################################################################################
# Set some defaults, allow overrides
TSS_CMD=${TSS_CMD:-ssh}
TSS_LAYOUT=${TSS_LAYOUT:-even-vertical}
TSS_OPTIONS=${TSS_OPTIONS:-"bind-key k kill-session\; bind-key = setw synchronize-panes\;"}
if [ -z "$2" ] && ! echo "$1" | grep ',' >/dev/null; then
echo "Syntax: tmux-sync-split <host1,host2,host3,...|host1 host2 host3 ...>"
exit 1
fi
host_list=""
if [ ! -z "$2" ] && ! echo "$1" | grep ',' >/dev/null; then
host_list="$*"
else
host_list=$(echo "$1" | sed 's/,/ /g')
fi
tmux_cmd=""
for host in ${host_list}; do
# Reset default inner cmd on each loop to include input host
inner_cmd_line="${TSS_CMD} ${host}"
if [ -z "${tmux_cmd}" ]; then
# If asked to avoid supplying input host..
if [ ! -z "${TSS_NOHOST}" ]; then
inner_cmd_line="${TSS_CMD}"
fi
#shellcheck disable=SC2089
tmux_cmd="${TSS_OPTIONS}\; new-session '${inner_cmd_line} ; read'\; set remain-on-exit\;"
else
tmux_cmd="${tmux_cmd} split-window -v '${inner_cmd_line} ; read'\; select-layout ${TSS_LAYOUT}\;"
fi
done
# already have a trailing semicolon here
tmux_cmd="${tmux_cmd} select-layout ${TSS_LAYOUT}\; set-window-option synchronize-panes"
eval tmux "${tmux_cmd}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment