【问题标题】:Pexpect Mulitple Line OutputPexpect 多行输出
【发布时间】:2022-08-18 23:31:31
【问题描述】:

问题

如何使用 pexpect 获得具有多行输出的命令的输出?

例子

这段代码有效,尽管输出被分成了一行:

child = pexpect.spawn(\'ping -c 3 1.1.1.1\')
child.expect(pexpect.EOF)
print(child.before)

但是,此代码不起作用:

child = pexpect.spawn(\'hostname\')
child.expect(pexpect.EOF)
print(child.before)

child.seldline(\'ping -c 3 1.1.1.1\')
child.expect(pexpect.EOF)
print(child.before)

我将如何让第二个代码工作?

背景

我有需要运行才能连接的命令(在此处替换为主机名),然后是输出多行的命令(在此处替换为 ping),我似乎无法从中获取输出。如果我查找 EOF 以外的任何字符串,我会收到 EOF 异常...

如果您需要证明,我实际运行的命令在这里:

这个其他问题的答案可能已被弃用,因为这部分代码完全复制只是一遍又一遍地输出b\'\'

  • 您没有包含多行的命令。您有多个单独的命令。您需要在此处对pexpect.spawn 使用两个单独的调用。一旦您expect EOF,该命令就完成了。你不能用它做更多的事情。
  • 这不是我可以分开的命令。它是一个 ssh、一个 lxc-attach 和另一个 ssh。然后我运行一个类似 ping 的命令。
  • 您是否在第一个 ssh 会话中运行 lxc-attachsshping?如果是这样,那么在结束会话之前您不会获得 EOF。您需要等待触发下一个操作的字符串,通常是 shell 提示符。
  • 我可以很好地运行这些命令,然后运行像hostname 这样的简单命令,但如果我执行多行操作(如ping),它就不起作用了。

标签: python pexpect


【解决方案1】:

生成一个将保持打开状态的 PID

真正的问题:为什么第二个例子不起作用。

pexpect.spawn 对象(此处为“child”)指向进程 ID (PID)。我尝试使用的示例不起作用,因为 hostname 正在运行然后退出。在我的实际用例中,我使用了ssh,然后在长输出命令之前使用了其他几个必要的步骤(此处由ping 表示)。

使用持续运行的命令启动多步骤流程将解决该问题。这些示例中的任何一个都可以使用:

child = pexpect.spawn('ssh user@host')
child = pexpect.spawn('bin/bash')

我切换到后者,它启动了一个可以与之交互的新外壳。这使我可以向 ssh 连接添加一些错误处理,并在一个 shell 中多次重用代码。

请注意,如果您分别退出 ssh 连接或 bash shell,则需要生成一个新的“孩子”来发送更多命令。

使用非阻塞读取

额外细节:修复第一个/工作示例的输出。

此代码将返回最后一个命令的输出而不更改它。

def try_read(child):
    """Based on pexpect.pxssh.try_read_prompt"""
    total_timeout = 3
    timeout = 0.5
    inter_char_timeout = 0.1
    begin = time.time()
    expired = 0
    prompt = ''
    while expired < total_timeout:
        try:
            prompt += child.read_nonblocking(size=1, timeout=timeout)
            expired = time.time() - begin # updated total time expired
            timeout = inter_char_timeout
        except TimeoutError:
            print("read ended with TimeoutError")
            break
        except pexpect.TIMEOUT:
            print("read ended with pexpect.Timeout")
            break
        except pexpect.EOF:
            print("read ended with pexpect.EOF")
            break
    return prompt

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-22
    • 2013-02-23
    • 1970-01-01
    • 1970-01-01
    • 2013-02-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多