由于公司项目,升级需要涉及到对端ssh过去取数据,但是如果碰到非免密登陆的,则会一直提示输入密码,卡死在进程里面;
网上查找思路,只有找到expect自动登陆;之前想过写自动登陆脚本,由于密码不太确定,且防止泄密风险;没有做
expect脚本如下,使用方法:/usr/bin/expect expect.sh $dstIp
#/usr/bin/expect
set dstIp [lindex $argv 0]
set timeout 15
spawn /usr/bin/ssh $dstIp
expect {
"*yes/no*" { send "yes\r";exp_continue }
"*password*" { exit 126 }
"*Last login:*" { exit 0 }
timeout { exit 127 }
}
lindex参数,argv从0开始,代表第一个参数
set参数,赋值
spawn参数,启动后期参数,如果执行完需要直接交互,最后加上interact
expect捕获结果,send参数,发送指令
timeout设置超时时间,以秒为单位;如果不满足其他条件,超过timeout就拖出
找了台没有设置免密登陆的机器,执行/usr/bin/expect expect.sh $dstIp
echo $?结果返回126;随便发了个ip测试超时,返回127
皆大欢喜啊;以为就这么完了;
然后再代码中执行,调用/usr/bin/expect expect.sh $dstIp;悲催,一直都是返回0;
使用-x执行,查看细节,发现执行进去了,然后就出来了,exit值收不到啊;
此刻开始怀疑人生,查找expect的细节,-d可以查看expect的细节;
调用/usr/bin/expect -d expect.sh $dstIp,一阵莫名激动
发现所有的expect都执行了,就是走到 "*password*" { exit 126 } 然后退出了;
感觉exit 错误,应该没有地方接收;怎么办,很绝望;
继续学习expect,spawn类似起一个子进程,可能子进程还没有结束,拿不到结果。
想到EOF,这个无底洞,肯定能够塞进去一万个结果了;
修改代码:
#/usr/bin/bash
desIp=$1
/usr/bin/expect<<EOF
set timeout 15
spawn /usr/bin/ssh $dstIp
expect {
"*yes/no*" { send "yes\r";exp_continue }
"*password*" { exit 126 }
"*Last login:*" { exit 0 }
timeout { exit 127 }
}
expect eof
exit 0
EOF
调用脚本,echo $?能够拿到了,都正确;
激动激动,想到马上嵌入到使用脚本中
还是不行;绝望了;
最后没办法,只能不封装接口了,把这段代码直接加入到脚本之中,就ok了;
至此:还不明白为啥封成接口就不支持了??
原因:调用expect.sh,在expect起了一个子进程(通过 -d能够看到进程号),ssh $dstIp,然后exit结果退出,结果写入EOF,当expect.sh退出返回结果,此时EOF又回到upgrade.sh的EOF,所以一直为0