【问题标题】:Pexpect not working at Yes/No promptPexpect 在是/否提示下不工作
【发布时间】:2018-10-01 03:20:43
【问题描述】:

我正在使用 pexpect 在 cisco 路由器上登录和运行命令。它卡在 RSA 是/否提示上,而不是发送“是”。这是代码的sn-p:

fout = file(filepath,'w')
child = pexpect.spawn('ssh %s@%s' % (username, agg))
child.logfile_read = fout
rsa_key = '\(yes\/no\)\?' 
prompt = "Password:"
i = child.expect([rsa_key,prompt,""])
if i==0:
    child.sendline('yes')
    child.expect(prompt)
    child.sendline(password)
elif i==1:
    child.sendline(password)
else:       
    child.sendline(password)

child.expect('>')
child.sendline('enable')
child.expect('Password:')
child.sendline(password)
child.expect('#')
child.sendline('terminal length 0')
child.expect('#')
child.sendline('show processes cpu history')
child.expect('#')
child.sendline('logout')

这是我得到的错误:

Traceback (most recent call last):
  File "/usr/pre_check.py", line 378, in <module>
    agg_check = agg_checks(agg,username,password)
  File "/usr/pre_check.py", line 198, in agg_checks
    child.expect('>')
  File "/usr/local/lib/python2.7/dist-packages/pexpect/spawnbase.py", line 327, in expect
    timeout, searchwindowsize, async_)
  File "/usr/local/lib/python2.7/dist-packages/pexpect/spawnbase.py", line 355, in expect_list
    return exp.expect_loop(timeout)
  File "/usr/local/lib/python2.7/dist-packages/pexpect/expect.py", line 104, in expect_loop
    return self.timeout(e)
  File "/usr/local/lib/python2.7/dist-packages/pexpect/expect.py", line 68, in timeout
    raise TIMEOUT(msg)
pexpect.exceptions.TIMEOUT: Timeout exceeded.
<pexpect.pty_spawn.spawn object at 0x7f6c5e4b89d0>
command: /usr/bin/ssh
args: ['/usr/bin/ssh', 'username@router']
buffer (last 100 chars): 'TyefPiveH4nHv1dfvbL/MFbqSR+dup1U7Cn+JaDeq0.\r\nAre you sure you want to continue connecting (yes/no)? '
before (last 100 chars): 'TyefPiveH4nHv1dfvbL/MFbqSR+dup1U7Cn+JaDeq0.\r\nAre you sure you want to continue connecting (yes/no)? '
after: <class 'pexpect.exceptions.TIMEOUT'>
match: None
match_index: None
exitstatus: None
flag_eof: False
pid: 28991
child_fd: 7
closed: False
timeout: 30
delimiter: <class 'pexpect.exceptions.EOF'>
logfile: None
logfile_read: <open file 'mylogfile.txt', mode 'w' at 0x7f6c5e53ee40>
logfile_send: None
maxread: 2000
ignorecase: False
searchwindowsize: None
delaybeforesend: 0.05
delayafterclose: 0.1
delayafterterminate: 0.1
searcher: searcher_re:
    0: re.compile(">")

我尝试了不同版本的 rsa_key 变量,但遇到了同样的问题:

  • 确定要继续连接(是/否)\?
  • 确定要继续连接(是/否)?
  • 确定要继续连接
  • (是/否)?
  • (是/否)\?
  • (是/否)

这是 ssh 到交换机时的样子:

ssh username@routername
The authenticity of host 'routername (11.111.111.1)' can't be established.
RSA key fingerprint is SHA256:KCS1HKzltOwHgg+WhTsV3OTxNzxUQwN9T3Jp1lGVu00.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'routername,11.111.111.1' (RSA) to the list of known hosts.
Password: 

routername>

【问题讨论】:

  • 为什么要给expect打电话的名单见:pexpect.readthedocs.io/en/stable/api/…
  • @Adonis 该链接的第二和第三句:模式超载,可能采用多种类型。该模式可以是 StringType、EOF、已编译的 re 或任何这些类型的列表。 该部分中的大多数示例也将列表传递给 expect()。不过,不确定空字符串的用途是什么。
  • @glibdud 糟糕,我只看了签名... OP 能否提供提示的样子?也许您可以尝试使用像 (".*yes/no.*") 这样的正则表达式?
  • 更新了 ssh 登录过程的样子。当 if 语句中有“else”时,需要空字符串。如果出于某种原因我有“else”而没有空字符串,它会中断。

标签: python pexpect


【解决方案1】:

就我个人而言,我会用ssh -o StrictHostKeyChecking=no 来回避这一点,因为您似乎不愿意根据任何解释做出决定。我不确定您将列表中的空字符串匹配的用例传递给期望调用,但是似乎无论索引如何,您都在发送密码并期待提示,就好像初始身份验证和主机检查已完成一样。您收到的错误显示缓冲区包含是/否提示,但在期待&gt; 时预计会失败。您的密码可能被发送到 yes no 提示,然后显示“请输入 'yes' 或 'no':”,其中不包含 &gt; 导致您超时。

【讨论】:

  • 就严格主机密钥检查而言,这是个好主意。那可能行得通。至于其他可能性,我已经尝试了我能想到的每一种组合,但它们不起作用。感谢您的帮助!
【解决方案2】:

您需要使用“(?i)yes/no”。我遇到了同样的问题。

【讨论】:

    猜你喜欢
    • 2012-11-08
    • 2017-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-17
    相关资源
    最近更新 更多