预期:^不适用于描述不同Cisco设备命令提示符的正则表达式

时间:2019-02-20 10:23:43

标签: regex tcl expect

我目前正在优化Expect脚本,以收集来自不同类型的Cisco设备的信息,并在正则表达式方面存在其他问题。非常感谢您的提前帮助。

背景/问题:Cisco Nexus设备在命令输出中使用“#”和“#”,这会影响脚本逻辑,该脚本逻辑在发送下一条命令之前使用相同的字符来识别命令提示符。

我可以使用以下更具体的命令提示符定义来解决大多数问题:

set prompt {([A-Z,a-z,0-9]+)(%|#|>|\\$)[\\ ]?$}

,然后在脚本中:

expect -re $prompt
send "$cmd\r"

现在我想使这个正则表达式更加具体, “行的开始,然后提示” 通过在正则表达式的开头添加一个尖括号“ ^”,但这会失败,并且脚本总是在发送下一个cmd之前进入超时状态。

set prompt {(^[A-Z,a-z,0-9]+)(%|#|>|\\$)[\\ ]?$}

这也失败

set prompt {^([A-Z,a-z,0-9]+)(%|#|>|\\$)[\\ ]?$}

在日志文件中,我看到命令提示符前面是CR(^ M,0x0d)。

更令人好奇的是,它仍然可以正常运行而不会超时,因此,是的,在Cisco CLI提示符前面有一个CR:

set prompt {[\x0d]([A-Z,a-z,0-9]+)(%|#|>|\\$)[\\ ]?$}

但是使用“ ^”时不是这样

set prompt {^[\x0d]([A-Z,a-z,0-9]+)(%|#|>|\\$)[\\ ]?$}

使用更少的时间浏览日志文件时,我看到以下内容:

^MDevice123# term len 0^M
^MDevice123# show inventory^M

Hexdump在行尾和新行之间显示,提示:

0d 0d 0a 0d (CR CR LF CR)

任何线索,我的目标出了什么问题,通过描述从开始到行尾的提示来使命令提示符的正则表达式更加具体?

1 个答案:

答案 0 :(得分:2)

^会匹配 buffer 的开头,而不仅仅是行的开头。

由于Expect是基于Tcl构建的,因此您可以使用Tcl regex syntax来表示您希望^匹配任何换行符之后的空字符串:

set prompt {(?n)^[[:alnum:]]+[%#>$]\s?$}
# ..........^^^^

注意:

  • 在方括号表达式中,使用逗号表示您也要匹配逗号。您希望[A-Z,a-z,0-9]而不是[A-Za-z0-9]匹配字母或数字,或使用上面显示的字符类。
  • 我怀疑您不需要捕获带括号的位。

在执行此操作时扩展到最后一点:

set prompt {([A-Za-z0-9]+)(%|#|>|\\$)[\\ ]?$}
expect -re $prompt

现在假设它可以按预期工作。还要假设您的提示如下:

myHostname1234>

expect之后,expect将捕获的正则表达式部分保存在expect_out数组中:

  • $expect_out(0,string)将包含与正则表达式匹配的文本
  • $expect_out(1,string)将包含由“([[A-Za-z0-9] +)”捕获的字母和数字,在这种情况下为“ myHostname1234”
  • $expect_out(2,string)将包含由“(%|#|> | \ $)”(在这种情况下为“>”
  • )捕获的提示符号

我怀疑您没有在代码中使用expect_out变量,因此无需期望麻烦就可以存储匹配的文本。我怀疑您真的不在乎提示符号是什么。

我知道对正则表达式的各个部分进行分组需要括号。但是,如果您不需要记住匹配的文本,则可以使用(?:subpattern)来获得分组行为,而无需记住行为。

expect_out数组还包含其他内容。阅读期望手册页以获取所有详细信息。