我想从一个新终端中的子进程获取用户输入。
import subprocess
additionalBuildArguments = "defaultarg1"
proc = subprocess.Popen(["python", "user_input.py", additionalBuildArguments],
creationflags=subprocess.CREATE_NEW_CONSOLE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
try:
outs, errs = proc.communicate(timeout=15)
except subprocess.TimeoutExpired:
proc.kill()
outs, errs = proc.communicate()
additionalBuildArguments = outs or additionalBuildArguments
user_input.py:
import sys
arg = sys.argv[1]
user_input = input(f"Additional build arguments [{arg}] (Push <ENTER> to use these settings):n")
print(user_input)
,只要我不设置stdout=子进程。管和/或stderr=subprocess。管选项我可以输入。但有了这些选项,我就无法向控制台写入任何输入。实际上,我需要这些选项来重定向标准输出,以便访问打印的user_input在父进程中。有人知道问题出在哪里吗?
请注意,我不明白你为什么要这样做,我本能地觉得你不应该这样做。然而,这是完全可能的:只处理stdout:
import sys
from subprocess import run
print("Type away: ", end="")
sys.stdout.flush()
r = run(["python", "-c", "print(input())"], capture_output=True, encoding="utf8")
print(f"You entered {r.stdout}")
编辑显然你正在使用窗口。根据文档,当shell=True
。对于shell=True
,这对我有用,但我不知道它是否适合你:
import sys
from subprocess import run
print("Type away: ", end="")
sys.stdout.flush()
r = run("python -c 'print(input())'", capture_output=True, shell=True, encoding="utf8")
print(f"You entered {r.stdout}")
可以链接到第三个进程中运行,该进程需要在从子进程捕获标准输出的同时进行打印。但是现在我们处于的领域非常可怕的hack.
一个更好的,但仍然是黑客的解决方案,是重新表述问题。你想要生成一个终端,这显然是可以做到的,并且用户可以正确地与它交互,然后你想要在生成代码中从那个终端获得输出。STDOUT不是此通信的适当通道。就我个人而言,我将我的代码结构是这样的:
生成代码:
- 生成参数化脚本,在生成的终端中运行,并将其保存为临时文件
- 衍生子终端运行生成的脚本
- 等待完成
- 读取临时文件并获取数据
- 删除临时脚本和临时输出文件
在生成的代码中:
- 做尽可能多的(毕竟你有一个完整的python)
- 将输出作为json转储到临时文件
这仍然是黑客,但它只涉及生成一个终端。注意,我仍然不明白为什么你要这样做,但这至少应该工作。