从 python 子进程调用 bash 维护上下文,返回结果并打印到屏幕

问题描述 投票:0回答:1

我有一个向 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
,会有多大的区别。在我看来,它们几乎是同一件事,但我显然在这里遗漏了一些重要的东西。我读过很多其他问题,它们解决了保留上下文、返回值或实时打印的问题,但从来没有同时解决这三件事。

python bash subprocess stdin popen
1个回答
0
投票
您可以使用以下命令来控制和交互式 shell

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()
根据您的需求进行调整。

© www.soinside.com 2019 - 2024. All rights reserved.