Python 子进程捕获 STDIN 输入并等待

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

我正在使用 Django 创建一个在线 python 编译器。

我有这个代码用于执行代码

def stream_response():
            try:
                process = subprocess.Popen(['python', temp_code_file_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin = subprocess.PIPE)
                process.stdin.write(b'Hello')
                for line in iter(process.stdout.readline, b''):
                    yield f"data: {line.decode('utf-8')}\n\n"
                    
                for line in iter(process.stdin.readline, b''):
                    yield f"data: {line.decode('utf-8')}\n\n"
                for line in iter(process.stderr.readline, b''):
                    yield f"data: {line.decode('utf-8')}\n\n"
            finally:
                os.unlink(temp_code_file_path)

但是,如果文件包含输入语句,例如,流处理可以正常工作

print("Hello") 
name = input("Enter your name: ") 
print(name)

“输入您的姓名:”未进行流式传输。我如何才能将其发送到我的客户端,运行特定的 javascript 并将输入附加到 DOM,获取用户输入并将其传达给子进程 STDIN?

我尝试过这些问题:

python-使用标准输入与子进程通信

python 中的子进程管道上的非阻塞读取

如何写入-python-subprocess-stdin)

但找不到适用于我的用例的解决方案

python subprocess
1个回答
0
投票

确保关闭标准输入。您可以使用

communicate()
将数据发送到 stdin,这会自动关闭 stdin。

main.py:

import subprocess, sys, os

temp_code_file_path = "/tmp/foo.py"
interpreter = os.path.abspath(sys.executable)
name_value = "Foobar"

process = subprocess.Popen(
    [interpreter, temp_code_file_path], 
    stdout=subprocess.PIPE, 
    stderr=subprocess.PIPE, 
    stdin = subprocess.PIPE
)

process.stdin.write(f"{name_value}\n".encode())
out, err = process.communicate()
process.wait()

#Everything from above just in one line:
#out, err = process.communicate(f"{name_value}\n".encode()) 


if process.returncode == 0:
    print("Subprocess successfully executed!")
    print(out.decode())
else:
    print("ERROR, running subprocess:")
    print(err.decode())

foo.py:

print("Hello") 
name = input("Enter your name: ") 
print(f"Your name is: {name}")

出:

Subprocess successfully executed!
Hello
Enter your name: Your name is: Foobar
© www.soinside.com 2019 - 2024. All rights reserved.