子进程读取线卡住

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

我正在尝试构建一个基于用户输入工作的终端。我设法获得输出,但 readline() 在生成输出后挂起。无论如何,在用户命令执行后是否停止 readline 。我添加了一个小示例函数来演示该问题:


def communicate_with_subprocess(process, command):
    try:
        # Send the command to the subprocess
        process.stdin.write(command + '\n')
        process.stdin.flush()

        lines = []

        # Read the output from the subprocess
        for _line in iter(process.stdout.readline, b''):
            if _line == '':
                break
            lines.append(_line)

        return lines

    except Exception as e:
        print(f"Error executing command '{command}': {e}")
        return None

# Example usage:
subprocess_instance = subprocess.Popen(["/bin/bash"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)

try:
    while True:
        user_input = input("Enter a command (type 'exit' to quit): ")

        if user_input.lower() == 'exit':
            print("Exiting...")
            break

        output = communicate_with_subprocess(subprocess_instance, user_input)
        print("Output:", output)

finally:
    subprocess_instance.terminate()
    subprocess_instance.wait()

目标是将其集成到 Django Web 应用程序中,因此如果有任何不涉及子流程的替代解决方案,也可以工作。

python django subprocess
1个回答
0
投票

好吧,我更深入地研究了它。你想做的事情是不可能的。

问题是线

process.stdout.readline
。如果您的子流程中没有任何内容可供读取,则会无限期地等待(正如您所经历的那样)。通常这不是问题,因为您在发出命令后关闭了子进程。但是你想保持它打开,因此你的阅读进程(主脚本/Django)应该如何知道你的子进程没有什么可以打印出来的?也许您已经开始了一项长时间操作,每 10 分钟才产生一次输出。因此机制很简单:如果您调用
readline
,它会无限期地等待返回任何内容。

好吧...,现在怎么办?

您有多种选择:

  • 每次调用(@see communicate)后关闭子流程并在每次新调用时创建。
  • 您可以保留单个打开的 shell 进程,但由于上述问题,您必须以不同的方式进行通信。
© www.soinside.com 2019 - 2024. All rights reserved.