-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsshchain.sh
More file actions
executable file
·107 lines (94 loc) · 2.21 KB
/
sshchain.sh
File metadata and controls
executable file
·107 lines (94 loc) · 2.21 KB
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
#!/bin/bash
# read from an input file, compose excutable.sh to trigger chain login
# by using expect.
#
# Usage: Create a text file, type in the ssh user name. password, host
# address like following
# user1|password1|host1
# user2|password2|host2
# ...
#
# example:
# root|passwd|192.168.1.15
# user|w@e%%$$|192.168.1.102
#
# Then save it, for example, as input.txt.
# Run ./sshchain.sh input.txt
input=$1
lnumber=0
line=''
linecount=0
executable='executable.sh'
user=''
passwd=''
host=''
eof='n'
function readline ()
{
# auto skip empty line
line=''
while [[ $eof = 'n' && -z $line ]];do
lnumber=$((lnumber + 1))
line=`awk "NR == $lnumber" $input`
if [ $lnumber -ge $linecount ];then
eof='y'
fi
done
}
function initialize ()
{
echo '#!/usr/bin/expect' > $executable
echo 'set timeout 60'
echo "" >> $executable
chmod +x $executable
echo "spawn ssh $1@$3 -o ServerAliveInterval=300" >> $executable
echo 'expect "*?assword:"' >> $executable
echo "send \"$(printf "%q" $2)\\r\"" >> $executable
echo "" >> $executable
}
function composechain ()
{
echo 'expect "*@*~]*?"' >> $executable
echo "send \"ssh $1@$3 -o ServerAliveInterval=120\\r\"" \
>> $executable
echo 'expect "*?assword:"' >> $executable
echo "send \"$(printf "%q" $2)\\r\"" >> $executable
echo "" >> $executable
}
function lastline ()
{
echo "interact" >> $executable
}
# main flow
# if no argument present
if [ -z $1 ];then
echo "Usage: $0 <input file>"
exit 0
fi
# save total line number of the file
# wc will print number and file name as one line, so we need to strip
# file name from that line, and transfer the number from string to integer.
echo "Counting input file lines..."
linecount=`wc -l $input`
linecount=${linecount%$input}
linecount=$((linecount))
# first ssh connection is unique, cannot be done in a loop.
echo "Read first host."
readline
if [ -z $line ];then
echo "Cannot find even one valid line from file $input."
exit 0
fi
# start composing excutable for first ssh connection
echo "Composing executable..."
initialize ${line//'|'/' '}
# compose other chain ssh connections
until [[ -z $line || $eof = 'y' ]];do
readline
composechain ${line//'|'/' '}
done
# finish up
lastline
# run it
echo "Run executable..."
expect -f $executable