SSH session multiplexer
/ssh/ssh-multi.sh
This script opens a SSH session to each host passed as argument in a separate pane in a new window in Tmux, and then synchronizes the input on all panes in the window. So, in short, this script works similarly to the ClusterSSH utility but in a Tmux session and without leaving the command line.
Just pass each host as an argument to the script or, if your hosts are numbered, you can use a range expansion, like this:
ssh-multi.sh myhost-{1..5}.example.com
In that case, you’ll notice that the window name will take the form
myhost-X-example-com
.
Download
this script
Secondary click/Save as…
#!/bin/bash
#
# Copyright 2019 eth0 <ethernet.zero@gmail.com>
#
# This work is free. You can redistribute it and/or modify it under the terms of
# the GNU General Public License v3.0. See the COPYING-gpl3 file for more details.
#
#
# ssh-multi : a script to ssh multiple servers over multiple tmux panes with
# with all panes syncronized.
#
# Based on olsonbg : bin/ssh-multi.sh @ https://github.com/olsonbg/dotfiles
#
# Based on nomad-fr : https://github.com/nomad-fr/scripts-systems
#
# Based on D.Kovalov work : https://gist.github.com/dmytro/3984680
session="sshmulti"
usage() {
[[ -n "$*" ]] && echo -e "$*\n"
echo "Usage: $(basename "$0") host host host…"
}
window_name() {
local name="${1//./-}"
local result=''
local length
local i
shift
for host in "$@"; do
result=''
host="${host//./-}"
length=${#host}
for (( i = 0; i < length; i++ )); do
if [[ "${host:i:1}" == "${name:i:1}" ]]; then
result+="${host:i:1}"
else
result+=X
fi
done
name=$result
done
echo "$name"
}
starttmux() {
local hosts=("$@")
local launchedtmux=0
echo "Hosts: ${hosts[*]}"
local window="ssh-multi_$$"
window="$(window_name "${hosts[@]}")"
if [[ -z "$TMUX" ]]; then # If we're not in a tmux session, create one
tmux -u new-session -d -s "${session}" -n "${window}" ssh "${hosts[0]}"
launchedtmux=1
else # Get session name of current tmux session.
session="$(tmux display-message -p '#S')"
echo "Session: $session"
existing_windows="$(tmux list-windows -t "${session}" -F '#W' | grep -Ec "^${window}\$")"
(( existing_windows > 0 )) && window="$(( existing_windows + 1 ))_${window}"
echo "Window: $window"
tmux new-window -n "${window}" ssh "${hosts[0]}"
launchedtmux=0
fi
tmux select-pane -T "${hosts[0]%%.*}"
tmux set-window-option -t "${session}:${window}" pane-border-status top
tmux set-window-option -t "${session}:${window}" pane-border-format '[#{?pane_active,#[reverse],} #{pane_index}: #{pane_title} #[default]]'
unset 'hosts[0]';
sleep 1
for i in "${hosts[@]}"; do
echo "Host: $i (${session}:${window})"
tmux split-window -t "${session}:${window}" -h "ssh $i"
tmux select-pane -T "${i%%.*}"
done
tmux select-layout -t "${session}:${window}" tiled
tmux select-pane -t "${session}:${window}"
tmux set-window-option -t "${session}:${window}" synchronize-panes on
# Setup complete. If we were already inside a tmux session, then we should
# be on the newly created window with synchronized panes, otherwise, we
# need to connect to the new tmux session.
if (( launchedtmux == 1 )); then
tmux a -dt "${session}"
fi
}
checkopt() {
if [[ -z "$*" ]]; then
usage "Please provide a list of hosts."
return 1
fi
return 0
}
checkopt "$@" || exit 1
starttmux "$@"