source: trunk/tssh/tssh @ 134

Last change on this file since 134 was 134, checked in by g7moreau, 6 years ago
  • Add comment and ls much more readable
File size: 6.5 KB
RevLine 
[125]1#!/bin/bash
2#
[126]3# 2014/03/26 Gabriel Moreau <Gabriel Moreau(A)univ-grenoble-alpes.fr> - Initial release
[125]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
[128]28DEPENDS
[126]29   On Debian, you need the package
[128]30
[126]31    apt-get install tmux ncurses-bin wamerican nmap
32
33   wamerican (or wfrench...) is used to choose a random word in the file /usr/share/dict/words
34   for each new tmux session.
35   ncurses-bin is required for the tput command
36   to automatically split your terminal into several small panels.
37   nmap is only used for dynamic DNS domain and dynamic scan.
38   This is not mandatory for general use.
39
[128]40   By default, tssh use tput to know the number of columns and lines of your terminal.
41   It takes 10 lines and 40 columns for each windows by default.
42   If tput is not installed, the default is 16 windows...
43
[125]44AUTHOR
45   Gabriel Moreau
46
47COPYRIGHT
48   Copyright (C) 2014-2017, LEGI UMR 5519 / CNRS UGA G-INP, Grenoble, France
49   Licence : GNU GPL version 2 or later
50END_USAGE
51   }
52
[128]53export remote_command=''
[125]54export split_number=16
55if which tput > /dev/null
56then
57   export split_number=$(( ($(tput  lines)/ 10) * ($(tput  cols)/ 40) ))
58fi
59
60export dyn_domain=''
61if [ -e "${HOME}/.tsshrc" ]
62then
63   . "${HOME}/.tsshrc"
64fi
65
66# get options
67if [ $# -eq 0 ]; then usage; exit 1; fi 
[128]68while getopts "w:c:fvh" options
[125]69do
70   case ${options} in
71      w)
72         if echo ${OPTARG} | egrep -q '^[[:digit:]]+$' && [ ${OPTARG} -gt 0 ]
73         then
74            export split_number=${OPTARG}
75         else
76            usage
77            exit 2
78         fi
79         ;;
[128]80      c)
81         if echo ${OPTARG} | egrep -q '[[:alpha:]]'
82         then
83            export remote_command=${OPTARG}
84         else
85            usage
86            exit 2
87         fi
88         ;;
[125]89      f)
90         export fast='yes'
91         ;;
92      v)
93         export verbose='yes'
94         ;;
95      h|*)
96         usage
97         exit 3
98         ;;
99   esac
100done
101shift $((OPTIND - 1))
102[[ $1 = "--" ]] && shift
103
104cd /tmp/
105export base_path=$(mktemp -d tssh.XXXXXX)
106touch "/tmp/${base_path}/master"
107touch "/tmp/${base_path}/master-"
108touch "/tmp/${base_path}/master+"
109touch "/tmp/${base_path}/master--"
110touch "/tmp/${base_path}/master++"
111
112get_host_list () {
113   local cluster
114   for host in $*
115   do
116      mode=""
117      last_char="${host: -1}"
118      if [ "${last_char}" == "-" -o "${last_char}" == "+" ]
119      then
120         mode="${last_char}"
121         host="${host:0:${#host}-1}"
122      fi
123
[133]124      # short host without login part if any
125      justhost=${host#*@}
126     
127      cluster=$(grep "^${justhost}\b" ${HOME}/.csshrc | cut -f 2 -d '=')
[125]128      if [ "${cluster}" == "" ]
129      then
[133]130         # just a host to scan and add
[125]131         if [ "${fast}" != 'yes' ]
132         then
[133]133            # test if exists host
134            if host ${justhost} | grep -q 'not found'
[125]135            then
[133]136               [ "${verbose}" == 'yes' ] && echo Warning: ${justhost} does not exists
[125]137               continue
138            fi
[133]139            if ! nmap -p 22 -sT -PN ${justhost} | grep -q '\bopen\b'
[125]140            then
[133]141               if host ${justhost}.${dyn_domain} | grep -q 'not found' || ! nmap -p 22 -sT -PN ${justhost}.${dyn_domain} | grep -q '\bopen\b'
[125]142               then
[133]143                  [ "${verbose}" == 'yes' ] && echo Warning: ${justhost} is down
[125]144                  continue
145               else
[133]146                  [ "${verbose}" == 'yes' ] && echo Warning: remove ssh key of ${justhost}.${dyn_domain}
147                  host=${justhost}.${dyn_domain}
148                  ssh-keygen -q -R $(LANG=C host ${justhost} | awk '{print $4}')
[125]149               fi
150            fi
151         fi
[133]152         [ "${verbose}" == 'yes' ] && echo Warning: add ${host} on list with mode ${mode}
[125]153         echo "${host}" >> "/tmp/${base_path}/master${mode}"
154      else
[133]155         # cluster, jump in a recursive mode
156         [ "${verbose}" == 'yes' ] && echo Warning: recursive mode for cluster ${cluster} with mode ${mode}
[125]157         cluster=$(get_host_list "${cluster}${mode}")
158      fi
159   done
160   }
161declare -fx get_host_list
162
163get_host_list $@
164cat "/tmp/${base_path}/master+" >> "/tmp/${base_path}/master"
165for f in $(grep . "/tmp/${base_path}/master-")
166do
167   egrep "^${f}$" "/tmp/${base_path}/master+" && continue
168   echo "${f}" >> "/tmp/${base_path}/master--"
169done
170for f in $(grep . "/tmp/${base_path}/master")
171do
172   egrep "^${f}$" "/tmp/${base_path}/master--" && continue
173   echo "${f}" >> "/tmp/${base_path}/master++"
174done
175
[134]176# split master list in paquet of split_number computer
177sort -u "/tmp/${base_path}/master++" | split -l ${split_number} - /tmp/${base_path}/__splitted_
[125]178
[134]179# loop on each split windows
180for f in $(ls -1 /tmp/${base_path}/ | grep ^__splitted_)
[125]181do
182   session=$(shuf -n 1 /usr/share/dict/words | tr -cd "[:alpha:]")
183
184   IFS=$'\n' host=($(cat "/tmp/${base_path}/${f}"))
185
[128]186   tmux -2 new-session -d -s $session "ssh ${host[0]} ${remote_command}"
[125]187
188   for (( i=1 ; i < ${#host[@]} ; i++))
189   do
[128]190      tmux splitw -t $session "ssh ${host[$i]} ${remote_command}"
[125]191      tmux select-layout tiled
192   done
193
194   tmux set-window-option synchronize-panes on  > /dev/null
195   tmux set-window-option -g utf8 on            > /dev/null
196   tmux set -g default-terminal screen-256color > /dev/null
197   #tmux set-option -g set-clipboard on
198 
199   # Sane scrolling
200   #tmux set -g mode-mouse on
201   #tmux set -g mouse-resize-pane on
202   #tmux set -g mouse-select-pane on
203   #tmux set -g mouse-select-window on
204 
205   #set -g terminal-overrides 'xterm*:smcup@:rmcup@'
206 
207   # toggle mouse mode to allow mouse copy/paste
208   # set mouse on with prefix m
209   tmux bind m \
210      set -g mode-mouse on \; \
211      set -g mouse-select-pane on \; \
212      display 'Mouse: ON' > /dev/null
213      # set -g mouse-resize-pane on \; \
214      #set -g mouse-select-window on \; \
215   # set mouse off with prefix M
216   tmux bind M \
217      set -g mode-mouse off \; \
218      set -g mouse-select-pane off \; \
219      display 'Mouse: OFF' > /dev/null
220      #set -g mouse-resize-pane off \; \
221      #set -g mouse-select-window off \; \
222   # toggle Broadcast
223   tmux bind b set-window-option synchronize-panes
224
225   tmux attach -t $session
226done
227
228# Clean temporary folder
229[ -d "/tmp/${base_path}" ] && rm -rf "/tmp/${base_path}"
Note: See TracBrowser for help on using the repository browser.