以下简单的 expect 脚本的目标是获取主机名远程机器上的名称
有时预期脚本无法执行 ssh 到 $IP_ADDRESS (因为远程机器不活动等)
因此在这种情况下,预期脚本将在 10 秒后中断(超时 10),这是可以的,但是......
有两种选择
- 期望脚本成功执行 ssh ,并在远程机器上执行命令 hostname
- 由于超时 10 秒,预计脚本会中断
在这两种情况下,Expect 都会退出
- 如果 ssh 成功,则预期会在 0.5-1 秒后中断,但如果 ssh 不好,则预期会在 10 秒后中断
但我不知道期望脚本是否成功执行 ssh?
是否有可能识别超时过程?或者验证预期是否因超时而结束?
备注我的 Linux 机器版本 - red-hat 5.1
期望脚本
[TestLinux]# get_host_name_on_remote_machine=`cat << EOF
> set timeout 10
> spawn ssh $IP_ADDRESS
> expect {
> ")?" { send "yes\r" ; exp_continue }
>
> word: {send $PASS\r}
> }
> expect > {send "hostname\r"}
> expect > {send exit\r}
> expect eof
> EOF`
例如,如果我们没有连接到远程主机
[TestLinux]# expect -c "$get_host_name_on_remote_machine"
spawn ssh 10.17.180.23
[TestLinux]# echo $?
0
答案1
您可以预期超时,某些版本需要 -timeout 就像 -regex 一样来测试超时的调用。
你期望的语句可能会变成
expect {
")?" { send "yes\r" ; exp_continue }
word: { send $PASS\r}
timeout { puts "failed to SSH" }
}
答案2
我知道这不是你真正想要的,但我想提供一个替代方案。使用 ssh 密钥代替密码,使用 bash 脚本代替 Expect:
output=$(ssh -o ConnectTimeout=10 -o BatchMode=yes -o StrictHostKeyChecking=no $IP_ADDRESS "hostname")
if [ $? -eq 255 ]; then
# Some error occured while attempting to connect.
else
# Success!
fi
这并没有明确地告诉您存在超时或使用私钥登录失败等情况,但它比编写 Expect 更好。