python - 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}')
解决方案
这有效:
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
而不是print
and sys.exit
:
def err(msg):
sys.stderr.write('{ERR}*{CLR} {}\n'.format(msg, **THEME))
sys.stderr.flush()
推荐阅读
- python - Python安排一个函数每隔几秒运行一次
- python - 在优化之前使用目标函数中的变量值:Python Gurobi
- javascript - HTML,CSS - 滑动时显示两张照片
- php - XAMMP 和 php 中的新功能:安装时出现此错误
- android - jetpack compose 可点击点击效果 类似 iOS
- excel - 需要对 VBA 脚本进行一些解释
- javascript - .Replace 不是替换文本
- django - 如何在不使用中间件的情况下从 require_http_methods 重定向?
- android - Sentry Cli - 缺少 proguard 映射文件
- apache-spark - 如何在 mapgroupwithstate 中仅保持状态 100 分钟