我有一个向 bash 发送语句的函数。它实时打印输出到控制台,并且还返回值。它工作完美,看起来像这样:
def call_in_bash(statement):
process = subprocess.Popen(['bash','-c',statement],stdout=subprocess.PIPE, universal_newlines=True, bufsize=1)
buffer = io.StringIO()
selector = selectors.DefaultSelector()
selector.register(process.stdout, selectors.EVENT_READ)
line = ''
while process.poll() is None:
events = selector.select()
for key, mask in events:
line = key.fileobj.readline()
buffer.write(line)
sys.stdout.write(line)
selector.close()
output = buffer.getvalue()
buffer.close()
return output
但是,我想将其设为具有构造函数和析构函数的类,以便后续调用可以保留上下文,直到我销毁该对象。也就是说,我可以在该文件夹中按
call_in_bash("cd folder")
,然后按 call_in_bash("do something")
。为此,我尝试做这样的事情:
def __init__(self):
self.process: Popen(['bash'], stdin=subprocess.PIPE, stdout=subprocess.PIPE ...)
def call_to_bash(self, statement):
self.process.stdin.write(statement + "\n")
self.process.stdin.flush()
# from here on same as before
无论命令如何,它都会锁定并且永远不会完成。我不知道如果我调用 popen(['bash']
然后将内容放入其标准输入而不是调用
bash -c statement
,会有多大的区别。在我看来,它们几乎是同一件事,但我显然在这里遗漏了一些重要的东西。我读过很多其他问题,它们解决了保留上下文、返回值或实时打印的问题,但从来没有同时解决这三件事。
pexpect
:
#! /usr/bin/env python3
import pexpect
import sys
PROMPT = r"bash-5.2\$ "
c = pexpect.spawn("bash -i", encoding="utf-8")
c.logfile = sys.stdout
c.expect(PROMPT)
c.sendline("cd /tmp")
c.expect(PROMPT)
c.sendline("ls -l")
c.expect(PROMPT)
c.close()
根据您的需求进行调整。