1

我正在尝试编写一个 python 脚本来访问多个 Cisco 网络设备。遗憾的是,这些设备的设置不一样,有些设备的横幅出现在奇怪的地方。这些横幅可能具有与提示可能具有的某些相同内容的模式。

例如,一旦我登录,我希望得到一个提示'hostname#',所以我基本上使用 apexpect('#') 我可能必须处理某些其他提示,例如'hostname>'as well so pexpect('>')works。我真的会有一个可能的提示列表,加上一个超时并采取相应的行动。

这很好,除非横幅出现在中间某处。例如,登录后可能会出现一个横幅,上面写着 ## Welcome ##并且在提示之前就在那里。我相信如果我可以告诉 pexpect 忽略正则表达式#.*\r我会很好,但我不确定这是可能的。是否可以让 pexpect 忽略一个字符串,或者有更好的方法来解决这个问题?

4

3 回答 3

2

我在BBS 时代使用的一个解决方案是查找提示,然后在我收到提示后立即查找换行符或超时一两秒的空格。如果第二次等待超时,那意味着我真的在等待提示。由于pexpect使用正则表达式,您实际上可以检查是否在提示后一秒钟内收到任何字符。

def wait_for_prompt(session, prompt, timeout=1):
    gotprompt = 0
    while not gotprompt:
        session.expect(prompt, timeout=None)
        gotprompt = session.expect([".", pexpect.TIMEOUT], timeout=timeout)

child = pexpect.spawn("ssh ...")
wait_for_prompt(child, "[#>] ?")

我以前从未真正使用过这个库,所以这可能需要一些调整,但这是我在 80 年代成功使用的一种方法。:-)

于 2012-06-01T16:24:56.257 回答
2

Python pexpect 模块等待匹配的输入。您实际上不能忽略输入,除非创建不匹配模棱两可或不需要的输入的正则表达式。但是,pexpect 也可以处理正则表达式列表,而不是创建一个非常复杂的正则表达式。然后锚定这些正则表达式以减少歧义。

例如,您可以通过将匹配锚定到行的开头或结尾并尽可能精确地区分命令提示符和横幅:

users = ['fred', 'ginger']
user_prompt = '^(?:%s)@.*?\$ $' % '|'.join(users)
child.expect (['hostname# $', 'hostname> $', user_prompt])

他们的关键是了解你想要匹配的输入,用锚构建一个明确的正则表达式,然后在你发现不匹配时更新你的表达式——希望不会太频繁,因为你没有创建过度贪婪的模式首先。

于 2012-06-01T17:15:53.757 回答
0

一旦 expect 找到了匹配项,它就会在流程实例上设置 'before'、'after' 和 'match' 属性。您可以使用这些来编写一些逻辑。

或者,您可以制作一个更好的正则表达式,只匹配您想要的提示。甚至 r'>$|#$' 也可能会做你想做的事,因为它只会匹配行尾的那些字符。

于 2012-06-01T16:10:43.673 回答