如何从 subprocess.Popen.stdout(非阻塞)读取所有可用数据? [英] How can I read all availably data from subprocess.Popen.stdout (non blocking)?

查看:63
本文介绍了如何从 subprocess.Popen.stdout(非阻塞)读取所有可用数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一种方法来读取 Popen 创建的流中所有当前可用的字符,或者找出缓冲区中剩余的字符数.

I need a way to either read all currently available characters in stream created by Popen or to find out how many characters are left in the buffer.

背景:我想用 Python 远程控制交互式应用程序.到目前为止,我使用 Popen 创建了一个新的子流程:

Backround: I want to remote control an interactive application in Python. So far I used Popen to create a new subprocess:

process=subprocess.Popen(["python"],shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE, cwd=workingDir)

(我并不是真正开始使用python,但实际的交互界面是相似的.)目前我读取了 1 个字节,直到我检测到进程已到达命令提示符:

(I'm not really starting python, but the actual interactive interface is similar.) At the moment I read 1 byte until I detect that the process has reached the command prompt:

output = ""
while output[-6:]!="SCIP> ":
    output += process.stdout.read(1)
    sys.stdout.write(output[-1])
return output

然后我通过 process.stdin.write("command\n") 开始一个冗长的计算.我的问题是,我无法检查计算是否完成,因为我无法检查流中的最后一个字符是否为提示.read()read(n) 阻塞我的线程,直到它到达 EOF,这永远不会,因为交互式程序在被告知之前不会结束.以上述循环的方式寻找提示也不起作用,因为提示只会在计算后出现.

Then I start a lengthy computation via process.stdin.write("command\n"). My problem is, that I cannot check whether the computation has finished or not, because I cannot check, whether the last characters in the stream are the prompt or not. read() or read(n) blocks my thread until it reaches EOF, which it never will, because the interactive program will not end until it is told to. Looking for the prompt in the way the above loop does won't work either, because the prompt will only occur after the computation.

理想的解决方案是允许我从流中读取所有可用字符并立即返回一个空字符串,如果没有可读取的内容.

The ideal solution would allow me to read all available character from the stream and immediately return an empty string, if there is nothing to read.

推荐答案

摸索我发现这个非常好的解决方案

Poking around I found this really nice solution

持久化 python 子进程

通过使用 fcntl 将子进程管道上的文件属性设置为非阻塞模式,无需辅助线程或轮询,从而避免了阻塞问题.我可能遗漏了一些东西,但它解决了我的交互式过程控制问题.

which avoids the blocking issue all together by using fcntl to set file attributes on the subprocess pipes to non-blocking mode, no auxiliary threads or polling required. I could be missing something but it has solved my interactive process control problem.

这篇关于如何从 subprocess.Popen.stdout(非阻塞)读取所有可用数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆