【问题标题】:python pexpect print output before or after matching the outputpython pexpect在匹配输出之前或之后打印输出
【发布时间】:2021-03-30 07:47:30
【问题描述】:

我正在使用pexpect 将输出与预期的字符串匹配。我还想将命令的输出打印到标准输出。我目前有这个:

def cliExecute(cmd):
    try:
        print("Running:", cmd)
        cli = pexpect.spawn(cmd)
        return cli
    except:
        print("Failed to execute command:", str(cmd), sys.exc_info()[0])
        print("Stopping test due to error")
        sys.exit(1)

def cliExpect(cli, expectation, timeout=30):
    try:
        # print(cli.read().decode()) Doing this will print o/p but the next command fails
        cli.expect(expectation, timeout=timeout)
    except:
        raise cliExpectFail("Failed to find: ", expectation,
            "\nLast exec line:" + str(cli.before))

当我使用cliExpect 时,上述逻辑与输出匹配,但我也想记录我匹配的输出。如果我添加 print(cli.read().decode()) 行,我会看到输出但匹配失败但是当我用 print 切换期望时,输出的打印不会发生。有关如何解决此问题的任何想法?

【问题讨论】:

标签: python pexpect


【解决方案1】:

readexpect/expect_exact 做不同的事情:

  • read 最适合强制输出,例如绘图,但没有缓冲区大小,它将一直读取直到遇到 EOF,有效地隐式关闭子节点(参见 pexpect.spawn.read)。
  • expect 读取spawn 或最后一个send/sendline 之后的所有输出,用于打开的子进程expect 通常不会关闭孩子,除非它达到 timeout(请参阅 pexpect.spawn.exact)。

这是我的意思的一个例子:

注意 - 在 Ubuntu 20.04 上测试,使用 Python 3.8

import pexpect

# This child executes a single command and closes implicitly
cli = pexpect.spawn("ls -l")
# I use expect_exact when using symbols like $ (also used by expect's regex)
index = cli.expect_exact(["$", pexpect.EOF, ])
if index == 0:
    print("First child still open, so use *before*:\n", cli.before)
    cli.close()
else:
    # This will happen
    print("First child closed, so use *read*:\n", cli.read())

# The child stays open after this command. You should close this child explicitly
cli = pexpect.spawn("/bin/bash")
index = cli.expect_exact(["$", pexpect.EOF, ])
if index == 0:
    # This will happen
    cli.sendline("ls -l")
    cli.expect_exact("$")
    print("Next child still open, so use *before*:\n", cli.before)
    cli.close()
else:
    print("Next child closed, so use *read*:\n", cli.read())

输出:

First child closed, so use *read*:
 b''
Next child still open, so use *before*:
 b'ls -l\r\ntotal 28\r\n-rw-rw-r-- 1 ***** ***** 3393 Dec  1 15:52 *****.py\r\n-rw-rw-r-- 1 ***** ***** 1071 Dec  1 21:54 cli.py\r\n-rw-rw-r-- 1 ***** *****  793 Nov 29 19:46 *****.py\r\n-rw-rw-r-- 1 ***** *****  796 Nov 29 19:37 *****.py\r\n-rw-rw-r-- 1 ***** ***** 1118 Nov 29 16:05 *****.py\r\n-rw-rw-r-- 1 ***** *****  709 Nov 29 16:21 *****.py\r\n-rw-rw-r-- 1 ***** *****  376 Nov 22 19:47 *****.log\r\n

如您所见,read 可能会被击中或错过。对于进出 CLI 命令,我建议改为 pexpect.run

import pexpect

list_of_commands = ["ls -l", ]
for c in list_of_commands:
    command_output, exitstatus = pexpect.run(c, withexitstatus=True)
    if exitstatus != 0:
        raise RuntimeError("Unable to {0}: {1}".format(c, command_output.strip()))
    print(command_output.strip().decode())

输出:

total 28
-rw-rw-r-- 1 ***** ***** 3393 Dec  1 15:52 *****.py
-rw-rw-r-- 1 ***** ***** 1071 Dec  1 21:54 cli.py
-rw-rw-r-- 1 ***** *****  793 Nov 29 19:46 *****.py
-rw-rw-r-- 1 ***** *****  796 Nov 29 19:37 *****.py
-rw-rw-r-- 1 ***** ***** 1118 Nov 29 16:05 *****.py
-rw-rw-r-- 1 ***** *****  709 Nov 29 16:21 *****.py
-rw-rw-r-- 1 ***** *****  376 Nov 22 19:47 *****.log

祝你的代码好运!

【讨论】:

    猜你喜欢
    • 2013-03-21
    • 2023-01-02
    • 2020-02-09
    • 1970-01-01
    • 2014-05-16
    • 1970-01-01
    • 2018-08-08
    • 1970-01-01
    • 2019-05-30
    相关资源
    最近更新 更多