【发布时间】:2021-05-28 08:31:38
【问题描述】:
我正在制作一个能够运行任何可执行文件的终端程序(请忽略安全问题)。我需要检测子进程何时等待用户输入(来自stdin)。我使用以下方式启动子进程:
process = subprocess.Popen(command, close_fds=False, shell=True, **file_descriptors)
我可以想到两种方法来检测子进程是否正在等待stdin:
- 写入一个字符,然后退格并检查子级是否处理了这 2 个字节。但是here 它说“CMD 确实支持退格键”。所以我需要找到一个字符,当打印到屏幕上时会删除命令提示符中
stdin缓冲区中的内容。 - 第二种方法是使用
pywin32library 和WaitForInputIdle函数,如here 所述。我查看了subprocess库的源代码,发现它使用pywin32并保留了对进程句柄的引用。所以我尝试了这个:
win32event.WaitForInputIdle(proc._handle, 100)
但是我收到了这个错误:
(1471, 'WaitForInputIdle', 'Unable to finish the requested operation because the specified process is not a GUI process.')
同样在 windows api 文档here 中它说:“WaitForInputIdle 只等待一次进程变为空闲;随后的 WaitForInputIdle 调用立即返回,无论进程是空闲还是忙碌。”。我认为这意味着我不能多次使用该功能,这不能解决我的问题
编辑:
这只需要在 Windows 上工作,但稍后我可能会尝试让我的程序也可以在 Linux 上计算。我也在为stdin/stdout/stderr使用管道。
为什么我需要知道孩子是否在等待标准输入:
目前,当用户按下回车键时,我将他们迄今为止写入的所有数据发送到stdin 并禁止用户更改它。问题是当子进程正在睡眠/计算并且用户写入一些输入并希望在进程再次开始从stdin 读取之前更改它。
基本上让我们来看看这个程序:
sleep(10)
input("Enter value:")
假设我输入了“abc\n”。使用 cmd 时,如果孩子还在睡觉,我可以按退格键并删除输入。目前我的程序会在检测到“\n”时将所有文本标记为只读并将其发送到stdin。
【问题讨论】:
-
这只需要在 Windows 上工作吗?
-
我找到了类似你想要的东西。它回答了你的问题吗? stackoverflow.com/a/49603436/11502612
-
@JosephSible-ReinstateMonica 我编辑了我的答案
-
@milanbalazs 我使用的是管道而不是文件,我不想更改子进程的输入。这就是我尝试将
"g\b"写入stdin的原因。\b字符应该删除另一个字符,但它只给了我"g"和一个白框 - 就像用于未知字符的那个。
标签: python-3.x subprocess pipe pywin32