forked from frankschubert/multi-ssh
-
Notifications
You must be signed in to change notification settings - Fork 1
/
multi-ssh.sh
executable file
·145 lines (130 loc) · 3.53 KB
/
multi-ssh.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!/bin/bash
GROUP_PATH=./groups/
# print usage info
usage () {
echo "usage: $0 [OPTION] [CMD]"
echo " -g|--group <GROUPNAME> (all|all-rhel6|all-squeezy)"
echo " -n|--dry-run don't run any command, only show them"
echo " -s|--silent don't show servernames"
echo " -c|--cron show servername only on remote output"
echo " -i|--stdin use stdin, even if CMD is not empty"
echo " CMD if empty, command is expected once(!) from stdin and sent to all (EOF expected!)"
exit
}
if [ $# -eq 0 ]; then
usage;
fi
gflag=0
dryrunflag=0
silentflag=0
cronflag=0
stdinflag=0
# Parse the command-line options
TEMP=`getopt -o g:nsci --long group:,dry-run,silent,cron,stdin \
-n $0 -- "$@"`
# Note the quotes around `$TEMP': they are essential!
eval set -- "$TEMP"
while true ; do
case "$1" in
-g|--group) gflag=1;
case "$2" in
"") echo "Groupname missing!"; usage; shift 2 ;;
*) GROUP=$2; shift 2 ;;
esac ;;
-n|--dry-run) dryrunflag=1; shift ;;
-s|--silent) silentflag=1; shift ;;
-c|--cron) cronflag=1; shift ;;
-i|--stdin) stdinflag=1; shift ;;
--) shift; break ;;
*) echo "Internal error!" ; exit 1 ;;
esac
done
if [[ $gflag = 0 ]]; then
usage;
fi
## generate grouplist
GROUP_LIST=""
### all
if [[ "$GROUP" == "all" ]]; then
GROUP_LIST=`cat $GROUP_PATH/*`
else
### location and type?
LOCATION_AND_TYPE=$(echo $GROUP |awk '/[a-z]+-[a-z]+/ { print 1 }')
if [[ "$LOCATION_AND_TYPE" = "1" ]]; then
#echo "Location and Type"
GROUP_LIST=$(cat $GROUP_PATH/$GROUP)
else
GROUP_LIST=$(cat $GROUP_PATH/*${GROUP}*)
fi
fi
## initialize some vars
HOST=""
PORT=""
STDIN_TEMPFILE=""
## save stdin to file, for multiple use in loop later
## only if $@ empty!
if [[ "$@" == "" || $stdinflag == 1 ]]; then
STDIN_TEMPFILE=$(mktemp)
cat /dev/stdin > $STDIN_TEMPFILE
fi
## loop through servers in group and execute specified command
for i in $GROUP_LIST; do
### ignore if first char is #
IS_COMMENT=$(echo $i |cut -c1)
if [[ "$IS_COMMENT" == "#" ]]; then
continue
fi
### get port
HOST=`echo $i |cut -d":" -f1`
PORT=`echo $i |cut -s -d":" -f2`
if [[ "$PORT" == "" ]]; then
PORT=22
fi
ssh -p $PORT $HOST "echo 0" &>/dev/null
CONNECT_TEST=$?
if [ "$CONNECT_TEST" != "0" ]; then
if [[ $silentflag == 0 && $cronflag == 0 ]]; then
echo "WARNING: $HOST:$PORT not reachable.";
fi
continue
fi
### don't print header on "silent" parameter
if [[ $silentflag == 0 && $cronflag == 0 ]]; then
echo "### $i ###"
fi
if [ $dryrunflag == 1 ]; then
if [[ "$@" == "" || $stdinflag == 1 ]]; then
echo "cat <STDIN> |ssh -p $PORT -T $HOST $@"
else
echo "ssh -p $PORT -T $HOST $@"
fi
else
if [ $cronflag == 1 ]; then
if [[ "$@" == "" || $stdinflag == 1 ]]; then
OUTPUT=$(cat $STDIN_TEMPFILE |ssh -p $PORT -T $HOST $@)
else
OUTPUT=$(ssh -p $PORT -T $HOST $@)
fi
if [[ "$OUTPUT" != "" ]]; then
if [ $silentflag == 0 ]; then
echo "### $i #######################################################################"
fi
IFS="
"
for line in $OUTPUT; do
echo $line
done
fi
else
if [[ "$@" == "" || $stdinflag == 1 ]]; then
cat $STDIN_TEMPFILE |ssh -p $PORT -T $HOST $@
#cat $STDIN_TEMPFILE |ssh -p $PORT -tt $HOST $@
else
ssh -p $PORT -T $HOST $@
#ssh -p $PORT -tt $HOST $@
fi
fi
fi
done
## cleanup
rm -f $STDIN_TEMPFILE