尝试在 python 中的文件对象上调用 readline() 但它暂停

发布于 2024-09-13 09:19:07 字数 276 浏览 10 评论 0原文

我使用 readline() 函数从通过 subprocess 模块获取的文件对象中读取数据:proc = subprocess.Popen(cmd, bufsize=0, stdout=subprocess.PIPE)。这允许我将 proc.stdout 作为类似文件的对象与 proc.stdout.readline() 一起使用。我的问题是,这会暂停等待输入,如果我进行 readline 调用时没有输入,我希望它超时并继续。我正在运行 Python 2.4,如何让 readline 方法停止暂停?谢谢。

I'm using the readline() function to read data from a file object obtained through the subprocess module: proc = subprocess.Popen(cmd, bufsize=0, stdout=subprocess.PIPE). This allows me to use proc.stdout as a file-like object with proc.stdout.readline(). My issue is that this pauses waiting for input and I'd like it to time out and move on if there isn't input there when I make the readline call. I'm running Python 2.4, how can I get the readline method to stop pausing? Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦在深巷 2024-09-20 09:19:07

在 posix-y 平台(基本上是除 Windows 之外的任何流行平台)上, select 模块为此目的提供了正确的工具。不幸的是,在 Windows 上,select 仅适用于套接字(不适用于 subprocess.Popen 将使用的管道),因此情况不太清楚。您需要在 Windows 上运行吗...?

如果没有,只需在 select.select 调用中使用子进程对象 pp.stdout.fileno() 并设置短超时 - - 这真的很容易!

编辑:这是一个简单的例子(当然假设需要导入):

>>> def f():                                                                    
...   p = subprocess.Popen("sleep 10; echo ciao", shell=True, stdout=subprocess.PIPE)
...   while True:                                                               
...     r, w, x = select.select([p.stdout.fileno()],[],[],1.0)
...     if r: return p.stdout.read()
...     print 'not ready yet'
... 
>>> f()
not ready yet
not ready yet
not ready yet
not ready yet
not ready yet
not ready yet
not ready yet
not ready yet
not ready yet
not ready yet
'ciao\n'
>>> 

请注意,没有办法“等待完整的行”:这会等待“任何输出”(然后阻塞,直到所有输出已准备好)。要阅读可用的内容,请使用 fcntl 来设置文件描述符上的 os.O_NODELAY (什么 fileno( ) 返回) 在开始循环之前。

On a posix-y platform (basically any popular platform except Windows), the select module offers the right tools for this purpose. Unfortunately, on Windows, select only works on sockets (not on pipes, which is what subprocess.Popen will be using), so the situation is not quite as clear there. Do you need to run on Windows...?

If not, just use the p.stdout.fileno() of your subprocess object p in a select.select call with a short timeout -- it's really easy!

Edit: here's a simple example (assuming the needed imports of course):

>>> def f():                                                                    
...   p = subprocess.Popen("sleep 10; echo ciao", shell=True, stdout=subprocess.PIPE)
...   while True:                                                               
...     r, w, x = select.select([p.stdout.fileno()],[],[],1.0)
...     if r: return p.stdout.read()
...     print 'not ready yet'
... 
>>> f()
not ready yet
not ready yet
not ready yet
not ready yet
not ready yet
not ready yet
not ready yet
not ready yet
not ready yet
not ready yet
'ciao\n'
>>> 

Note there is no way to "wait for a complete line": this waits for "any output at all" (then blocks until all the output is ready). To read just what's available, use fcntl to set os.O_NODELAY on the file descriptor (what fileno() returns) before you start looping.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文