Expect-Telnet脚本执行show version失败:spawn id未打开报错求助
问题分析
你遇到的expect: spawn id exp6 not open错误,核心原因是第一个expect块没有捕获登录成功后的命令提示符# ,导致脚本在登录完成后继续等待,触发超时并关闭了spawn进程,后续的expect "# "自然找不到有效的spawn连接了。另外脚本还有几处语法和逻辑细节问题,我帮你逐一修正:
关键修正点
- 修复脚本开头的语法错误:
#!/usr/bin/expect -f后需要换行,每个set命令单独一行 - 在第一个
expect块中加入对#的匹配,让登录流程完成后能正常退出该块,进入后续命令执行 - 替换Windows风格的换行符
为Unix/Linux下的\r,避免发送无效字符 - 移除
telnet -l cli中的-l cli参数(部分设备不支持telnet的用户名预填,反而会导致登录流程混乱) - 优化超时逻辑,避免误关闭连接
修正后的完整脚本
#!/usr/bin/expect -f set IP [lindex $argv 0] set timeout 10 set send_slow {10 .5} log_user 1 spawn telnet $IP expect { timeout { puts "Network Connection Problem" close exit } "Password:" { send -s -- "cli\r" exp_continue } "Username:" { send -s -- "admin\r" expect "Password:" send -s -- "admin\r" exp_continue } "(Y/N)?" { send -s -- "Y\r" exp_continue } "# " { # 登录成功,退出当前expect块 } } # 执行show version命令 expect "# " send -s -- "show version\r" # 可选:捕获命令输出并打印 expect "# " puts $expect_out(buffer) # 主动退出telnet连接 send -s -- "exit\r" close exit
修正细节解释
- 语法修复:脚本开头的
#!/usr/bin/expect -f必须单独占一行,后续每个变量定义也要单独成行,否则Expect会解析错误。 - 捕获登录成功提示符:在第一个
expect块中加入"# "的匹配分支,当登录完成出现命令提示符时,直接退出该块,避免脚本进入超时逻辑关闭连接。 - 换行符修正:用
\r替代,这是Unix/Linux环境下终端识别的回车符,确保输入能被设备正确接收。 - 移除
-l cli参数:很多网络设备不支持通过telnet -l预填用户名,反而会导致登录流程异常,改为脚本动态处理用户名提示更可靠。 - 添加主动退出逻辑:脚本最后主动发送
exit退出telnet连接,避免残留无用进程。
这样修改后,脚本就能正常完成登录并执行show version命令了。
内容的提问来源于stack exchange,提问作者Mokebe
相关产品推荐
相关产品推荐

