我目前正在优化期望脚本以从不同类型的思科设备收集信息,并在正则表达式方面存在休息问题。非常感谢您的帮助。
背景/问题:Cisco Nexus设备在命令输出中使用“#”和“#”,这会影响在发送下一个命令之前使用相同字符识别命令提示符的脚本逻辑。
我可以通过使用命令提示符的这个更具体的定义来解决大多数问题:
set prompt {([A-Z,a-z,0-9]+)(%|#|>|\\$)[\\ ]?$}
然后在脚本中:
expect -re $prompt
send "$cmd\r"
现在我想通过在正则表达式的开头添加一个carret“^”来使这个正则表达式更加具体,“开始行,然后提示”,但这会失败并且脚本在发送之前总是运行到超时下一个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]+)(%|#|>|\\$)[\\ ]?$}
当使用less来浏览日志文件时,我看到:
^MDevice123# term len 0^M
^MDevice123# show inventory^M
Hexdump在行尾和新行之间显示提示:
0d 0d 0a 0d (CR CR LF CR)
有什么线索我的目标出错了,通过描述从一开始到一行结尾的提示,使命令提示符的正则表达式更具体?
^
将匹配缓冲区的开头,而不仅仅是行的开头。
由于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_out
数组中保存正则表达式的捕获部分:
$expect_out(0,string)
将包含正则表达式匹配的文本$expect_out(1,string)
将包含“([A-Za-z0-9] +)”捕获的字母和数字,在本例中为“myHostname1234”$expect_out(2,string)
将包含由“(%|#|> | \ $)”捕获的提示符号,在本例中为“>”我怀疑你没有在你的代码中使用expect_out
变量,因此没有必要期望存储匹配文本的麻烦。我怀疑你真的不在乎提示符号是什么。
我知道括号需要对正则表达式的部分进行分组。但是,如果您不需要记住匹配的文本,则可以使用(?:subpattern)
来获取分组行为而不记住行为。
expect_out
数组也包含其他内容。阅读期望手册页了解所有细节。