需求
有n台服务器,只需要执行一个命令即可自动登录,而不需要再手动输入密码。
网上的方法
网上很多 expect
的教程,但是里面只是写死了一两个服务器而已,因为他们使用的头部是 #!/usr/bin/expect
,里面不能加入shell
的运行命令。如果是n台或者多台服务器,这种方式是执行不了的。所以需要能让shell命令和 expect命令共同运行才行。
解决方法
使用一个shell脚本,里面列出所有的服务器的登录信息,然后再进行expect执行。
#!/bin/bash
ibm1=("root" "XXXX" "33" "password1" "10.10.1.1")
ibm2=("root" "XXXX" "33" "password2" "10.10.1.2")
ibm3=("root" "XXXX" "33" "password3" "10.10.1.3")
ibm4=("root" "XX2XX" "33" "password4" "10.10.1.4")
ibm5=("root" "XXXX" "2222" "password5" "10.10.1.5")
aly1=("root" "XXXXX" "22" "password6" "11.2.3.1" "testoc")
aly2=("root" "XXXX" "22" "password7" "11.2.3.4" "gitlab")
servers=(ibm1[@] ibm2[@] ibm3[@] ibm4[@] ibm5[@] aly1[@] aly2[@])
ct=${#servers[@]}
echo "请输入公网IP 或标识:"
read ip
realip=
for ((i=0;i<$ct;i++))
do
serv=${!servers[i]}
echo $serv | awk '{print $2$6}' | grep $ip &>/dev/null
if [ $? == 0 ] ; then
realip=($serv)
break
fi
done
if [ ! -z "$realip" ]; then
echo "start login ${realip[1]} ${realip[5]}..."
expect -c "
set timeout -1
spawn ssh -p ${realip[2]} ${realip[0]}@${realip[1]}
expect {
\"*(yes/no)*\" { send \"yes\r\" }
\"password\" { send \"${realip[3]}\r\"; interact }
}
"
else
echo "Not Found.\n"
fi
注意事项
1)expect 等待为什么特别长
在里面必须加入一段 set timeout -1
2)为什么总是在等待,第一次登录的时候会有 提示要不要加入ssh-key。
这个时候写法必须是这样
expect {
\"*(yes/no)*\" { send \"yes\r\" }
\"password\" { send \"${realip[3]}\r\"; interact }
}
网上的如下写法是错误的:
expect "password:"
send "xxxxx\r"
interact
这样只会让一只在等待,可以直接在终端运行 expect
进行测试即可知道。 ( by coconets#163.com)