Expect不能识别Cisco路由器上的输出

我正在编写一个脚本, expect通过ssh自动configurationcisco路由器。 这个脚本的一部分是将图像复制到flash如果它不存在:

对于这个期望发送一个copy并等待Destination filename然后发送一个return

 cisco#copy tftp://10.xx.xx.3/name_of_image.bin flash: Destination filename [name_of_image.bin]? 

现在有两个select:

  1. 该文件不存在并被复制到flash:
  2. 该文件存在,脚本跳过这部分。

如果文件已经存在,它看起来像这样:

 %Warning:There is a file already existing with this name Do you want to over write? [confirm] 

现在到我的问题:脚本等待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" 

我究竟做错了什么?

有几件事是错误的:

  • 在一个双引号string[confirm]将尝试调用期望命令“确认” – 方括号期望是像反引号在壳
  • 期望需要用空格分隔参数。 因此,在开口大括号之前放置一个空间是非常重要的
  • 您的脚本不会期望有条件的覆盖提示。 您需要使用expect命令的多模式forms,其中第一个匹配成功。

尝试这个:

 expect { -exact {Do you want to over write? [confirm]} { send "\r" exp_continue } "*#" } send "exit\r" expect eof 

笔记

  • 我使用“精确”匹配,因为你有glob通配符? 并会干涉。
  • 我使用expect的无插值引号(大括号)来防止[confirm]尝试命令replace
  • 我期望覆盖提示命令提示符
  • 如果出现覆盖提示,我使用exp_continue保持在expect命令中。 这意味着我仍然可以查找命令提示符。
  • 以上2项是如何实现条件匹配的。
  • 我假设你只是想在覆盖提示中input。
  • exit ,等待eof ,让ssh会话正常结束