我正在编写一个脚本,用于expect
通过 自动配置思科路由器ssh
。此脚本的一部分是将图像复制到flash
不存在的图像中:
对于这个,expect 发送一个copy
,然后等待,Destination filename
然后发送一个return
。
cisco#copy tftp://10.xx.xx.3/name_of_image.bin flash:
Destination filename [name_of_image.bin]?
现在有两个选择:
- 该文件不存在并被复制到
flash:
- 该文件存在,脚本跳过此部分。
如果文件已经存在,则如下所示:
%Warning:There is a file already existing with this name
Do you want to over write? [confirm]
现在说说我的问题:脚本等待Do you want to over write? [confirm]
,然后应该退出,因为图像已经在闪存中了。但目前它似乎expect
无法识别该行,并卡在确认处。它尝试了几种模式,如[confirm]
、、等等。*[confirm]*
Do
*write*
我目前为这项工作编写的代码如下:
expect "*#"
send "copy tftp://10.$ip_local.3/name_of_image.bin flash:\r"
expect "Destination filename"
send "\r"
expect {
"Do you want to over write? [confirm]"{
interact
abort
}
expect "*#"
send "exit\r"
我究竟做错了什么?
答案1
有几件事情是错误的:
- 在双引号字符串中将
[confirm]
尝试调用 expect 命令“confirm”——expect 中的方括号类似于 shell 中的反引号 - expect 需要用空格分隔参数。因此,在左花括号前留一个空格至关重要
- 你的脚本不需要覆盖提示有条件的。您需要使用多模式形式的
expect
命令,其中第一个匹配的命令获胜。
尝试这个:
expect {
-exact {Do you want to over write? [confirm]} {
send "\r"
exp_continue
}
"*#"
}
send "exit\r"
expect eof
笔记
- 我使用“精确”匹配,因为您有全局通配符,
?
而且[...]
这会产生干扰。 - 我使用 expect 的无插值引号(花括号)来防止
[confirm]
尝试命令替换 - 我预计任何一个覆盖提示或者命令提示符
- 如果出现覆盖提示,我习惯
exp_continue
保留在此 expect 命令内。这意味着我仍然可以查找命令提示符。 - 以上2点是如何实现条件匹配。
- 我假设您只是想在覆盖提示时按回车键。
- 之后
exit
,等待eof
ssh 会话正常结束