如何编写正确的Expect脚本处理SSH登录的信任提示与密码输入?
解决Expect SSH脚本中首次登录确认+密码输入的问题
嘿,我刚碰到过类似的情况,给你说个靠谱的解决办法~
你之前的两种写法问题出在这儿:
- 第一种多分支expect:它是单次匹配,只要匹配到其中一个模式并执行动作后,就会退出这个expect块。所以如果先出现"yes/no",发送"yes"之后就不会再等密码提示了;反过来如果直接出现密码提示,倒是能正常处理,但第一次登录就会失败。
- 第二种顺序expect:如果已经信任过服务器,不会弹出"yes/no",第一个expect就会一直等超时,这就是你觉得输入密码前等很久的原因。
正确的写法:用exp_continue实现循环匹配
在处理"yes/no"的分支里加上exp_continue,这样发送"yes"之后,脚本会回到当前的expect块,继续等待后续的密码提示。代码如下:
expect { "yes/no" { send "yes\n" exp_continue ;# 继续等待当前expect块里的其他模式 } "assword: " { send "$mypass\n" } }
为什么这个写法能行?
- 首次登录时,先匹配到"yes/no",发送"yes"后,
exp_continue让脚本留在这个expect块里,继续监听密码提示,收到后就发送密码。 - 如果已经信任过服务器,不会出现"yes/no",脚本会直接匹配"assword: ",发送密码,不会有超时等待。
额外小技巧(可选)
如果你不想处理这个确认提示,也可以直接在SSH命令里加上参数跳过主机密钥检查:
ssh -o StrictHostKeyChecking=no user@server
这样Expect脚本里就只需要处理密码输入就行啦,但这个方法会跳过主机密钥验证,安全性稍低,看你的需求选择。
内容的提问来源于stack exchange,提问作者souser
相关产品推荐
相关产品推荐

