expect检查ssh登陆对端是否免密

由于公司项目,升级需要涉及到对端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<

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

你可能感兴趣的:(expect检查ssh登陆对端是否免密)