首页 > 解决方案 > Pexpect:无法写入 STDIN — 为什么?

问题描述

为什么这不起作用?

data, status = run('grep o', stdout=True, stdin='lol')
print(f'data: {data}, status: {status}')

完整代码:

import pexpect
import sys
def run(cmd, prompts=[], password=None, stdout=False, stdin=''):
    """runs and interacts with external commands"""
    child = pexpect.spawn(cmd, encoding='utf-8')
    for prompt in prompts:
        try:
            child.expect(prompt)
        except pexpect.exceptions.TIMEOUT:
            print(f'prompt "{prompt}" not matched')
            sys.exit(1)
        child.sendline(password)
    child.send(stdin)
    try:
        data = child.read() if stdout else None
    except pexpect.exceptions.TIMEOUT:
        print('command took too long to print to stdout')
        sys.exit(1)
    child.close()
    return data, child.exitstatus

data, status = run('grep o', stdout=True, stdin='lol')
print(f'data: {data}, status: {status}')

标签: pythonpexpect

解决方案


这有效:

def run(cmd, prompts=[], password=None, stdout=False, stdin=None):
    """runs and interacts with external commands"""
    child = pexpect.spawn(cmd, encoding='utf-8')
    for prompt in prompts:
        try:
            child.expect_exact(prompt)
        except pexpect.exceptions.TIMEOUT:
            err(f'prompt "{prompt}" not matched')
        child.sendline(password)
    if stdin is not None:
        child.sendline(stdin)
        child.sendeof()
        child.sendeof()
    try:
        data = child.read() if stdout else None
    except pexpect.exceptions.TIMEOUT:
        err('command took too long to print to stdout')
    exitstatus = child.wait()
    return data, exitstatus

差异:

  • child.send(stdin)->child.sendline(stdin)
  • child.sendeof()重复两次。对于这个特定示例(即运行),这不是必需的grep o,但对于 scrypt enc - out.enc. 我不知道为什么。

我不知道为什么上述任何一个都有效。如果你知道让我知道。

没关系,但我使用的是函数err而不是printand sys.exit

def err(msg):
    sys.stderr.write('{ERR}*{CLR} {}\n'.format(msg, **THEME))
    sys.stderr.flush()

推荐阅读