source: trunk/tssh/tssh @ 125

Last change on this file since 125 was 125, checked in by g7moreau, 3 years ago
  • Initial release from LEGI internal version
File size: 5.0 KB
Line 
1#!/bin/bash
2#
3# 2014/03/26 Gabriel Moreau
4#
5# From http://hd-recording.at/dokuwiki/doku.php?id=linux:tmux#tssh
6
7# Clean when Ctrl^C
8trap '[ -n "${base_path}" -a -d "/tmp/${base_path}" ] && rm -rf "/tmp/${base_path}"' QUIT
9
10export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin
11export LANG=C
12
13
14function usage() {
15   cat <<END_USAGE
16NAME
17   $(basename $0) - tmux cluster ssh
18
19SYNOPSIS
20   $0 [-w number] [-f] [-v] <host1> <host2> <clusterssh class>... <hostM>- <hostN>+
21
22OPTIONS
23   -w  windows to open (integer, default 16)
24   -f  fast, no nmap scan to eliminate sleeping computer
25   -v  verbose
26   -h  help
27
28AUTHOR
29   Gabriel Moreau
30
31COPYRIGHT
32   Copyright (C) 2014-2017, LEGI UMR 5519 / CNRS UGA G-INP, Grenoble, France
33   Licence : GNU GPL version 2 or later
34END_USAGE
35   }
36
37export split_number=16
38if which tput > /dev/null
39then
40   export split_number=$(( ($(tput  lines)/ 10) * ($(tput  cols)/ 40) ))
41fi
42
43export dyn_domain=''
44if [ -e "${HOME}/.tsshrc" ]
45then
46   . "${HOME}/.tsshrc"
47fi
48
49# get options
50if [ $# -eq 0 ]; then usage; exit 1; fi 
51while getopts "w:fvh" options
52do
53   case ${options} in
54      w)
55         if echo ${OPTARG} | egrep -q '^[[:digit:]]+$' && [ ${OPTARG} -gt 0 ]
56         then
57            export split_number=${OPTARG}
58         else
59            usage
60            exit 2
61         fi
62         ;;
63      f)
64         export fast='yes'
65         ;;
66      v)
67         export verbose='yes'
68         ;;
69      h|*)
70         usage
71         exit 3
72         ;;
73   esac
74done
75shift $((OPTIND - 1))
76[[ $1 = "--" ]] && shift
77
78cd /tmp/
79export base_path=$(mktemp -d tssh.XXXXXX)
80touch "/tmp/${base_path}/master"
81touch "/tmp/${base_path}/master-"
82touch "/tmp/${base_path}/master+"
83touch "/tmp/${base_path}/master--"
84touch "/tmp/${base_path}/master++"
85
86get_host_list () {
87   local cluster
88   for host in $*
89   do
90      mode=""
91      last_char="${host: -1}"
92      if [ "${last_char}" == "-" -o "${last_char}" == "+" ]
93      then
94         mode="${last_char}"
95         host="${host:0:${#host}-1}"
96      fi
97
98      cluster=$(grep "^${host}" ${HOME}/.csshrc | cut -f 2 -d '=')
99      if [ "${cluster}" == "" ]
100      then
101         if [ "${fast}" != 'yes' ]
102         then
103            # short host without login part if any
104            if host ${host#*@} | grep -q 'not found'
105            then
106               [ "${verbose}" == "yes" ] && echo Warning: ${host#*@} does not exists
107               continue
108            fi
109            if ! nmap -p 22 -sT -PN ${host#*@} | grep -q '\bopen\b'
110            then
111               if host ${host#*@}.${dyn_domain} | grep -q 'not found' || ! nmap -p 22 -sT -PN ${host#*@}.${dyn_domain} | grep -q '\bopen\b'
112               then
113                  [ "${verbose}" == "yes" ] && echo Warning: ${host#*@} is down
114                  continue
115               else
116                  host=${host}.${dyn_domain}
117                  ssh-keygen -q -R $(LANG=C host ${host} | awk '{print $4}')
118               fi
119            fi
120         fi
121         echo "${host}" >> "/tmp/${base_path}/master${mode}"
122      else
123         cluster=$(get_host_list "${cluster}${mode}")
124      fi
125   done
126   }
127declare -fx get_host_list
128
129get_host_list $@
130cat "/tmp/${base_path}/master+" >> "/tmp/${base_path}/master"
131for f in $(grep . "/tmp/${base_path}/master-")
132do
133   egrep "^${f}$" "/tmp/${base_path}/master+" && continue
134   echo "${f}" >> "/tmp/${base_path}/master--"
135done
136for f in $(grep . "/tmp/${base_path}/master")
137do
138   egrep "^${f}$" "/tmp/${base_path}/master--" && continue
139   echo "${f}" >> "/tmp/${base_path}/master++"
140done
141
142sort -u "/tmp/${base_path}/master++" | split -l ${split_number} - /tmp/${base_path}/_
143
144for f in $(ls -1 /tmp/${base_path}/ | grep -v ^master)
145do
146   session=$(shuf -n 1 /usr/share/dict/words | tr -cd "[:alpha:]")
147
148   IFS=$'\n' host=($(cat "/tmp/${base_path}/${f}"))
149
150   tmux -2 new-session -d -s $session "ssh ${host[0]}"
151
152
153   for (( i=1 ; i < ${#host[@]} ; i++))
154   do
155      tmux splitw -t $session "ssh ${host[$i]}"
156      tmux select-layout tiled
157   done
158
159   tmux set-window-option synchronize-panes on  > /dev/null
160   tmux set-window-option -g utf8 on            > /dev/null
161   tmux set -g default-terminal screen-256color > /dev/null
162   #tmux set-option -g set-clipboard on
163 
164   # Sane scrolling
165   #tmux set -g mode-mouse on
166   #tmux set -g mouse-resize-pane on
167   #tmux set -g mouse-select-pane on
168   #tmux set -g mouse-select-window on
169 
170   #set -g terminal-overrides 'xterm*:smcup@:rmcup@'
171 
172   # toggle mouse mode to allow mouse copy/paste
173   # set mouse on with prefix m
174   tmux bind m \
175      set -g mode-mouse on \; \
176      set -g mouse-select-pane on \; \
177      display 'Mouse: ON' > /dev/null
178      # set -g mouse-resize-pane on \; \
179      #set -g mouse-select-window on \; \
180   # set mouse off with prefix M
181   tmux bind M \
182      set -g mode-mouse off \; \
183      set -g mouse-select-pane off \; \
184      display 'Mouse: OFF' > /dev/null
185      #set -g mouse-resize-pane off \; \
186      #set -g mouse-select-window off \; \
187   # toggle Broadcast
188   tmux bind b set-window-option synchronize-panes
189
190   tmux attach -t $session
191done
192
193# Clean temporary folder
194[ -d "/tmp/${base_path}" ] && rm -rf "/tmp/${base_path}"
Note: See TracBrowser for help on using the repository browser.