2005年06月29日 星期三 13:51
我在程序中需要启动一个外部命令并读取该命令的输出。问题是这个外部命令在产 生第一部分输出后要停顿很长时间,而我并不想等到外部命令全部结束再去读取它 的输出,而想先得到第一部分的输出。 例如,假设外部程序是以下python代码: test.py: import sys, time print 'hello'*500 sys.stdout.flush() time.sleep(100) print 'world'*500 我希望在自己的程序中设置一个timeout,读取外部进程在这个timeout时间前的所 有输出,即前500个'hello'。我的程序是这样写的: import os, select cmd = 'python test.py' pin, pout = os.popen2(cmd) select.select([pout], [], [], timeout)[0] pout.read() 根据文档select应该等到pout有可读取的内容(即前500个'hello')时就返回,但实 际情况是它要一直到test.py全部执行完毕才返回可读的内容。 谁知道这段代码应该如何正确书写?代码运行在Linux下。 -- HONG Yuan 大管家网上建材超市 http://www.homemaster.cn
2005年06月29日 星期三 14:08
Skipped content of type multipart/mixed-------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/x-pkcs7-signature Size: 3066 bytes Desc: not available Url : http://lists.exoweb.net/pipermail/python-chinese/attachments/20050629/e587cf13/smime.bin
2005年06月29日 星期三 14:27
你这里不应该用read 应该用readline 2005/6/29, Hong Yuan <hongyuan at homemaster.cn>: > 我在程序中需要启动一个外部命令并读取该命令的输出。问题是这个外部命令在产 > 生第一部分输出后要停顿很长时间,而我并不想等到外部命令全部结束再去读取它 > 的输出,而想先得到第一部分的输出。 > > 例如,假设外部程序是以下python代码: > > test.py: > import sys, time > print 'hello'*500 > sys.stdout.flush() > time.sleep(100) > print 'world'*500 > > 我希望在自己的程序中设置一个timeout,读取外部进程在这个timeout时间前的所 > 有输出,即前500个'hello'。我的程序是这样写的: > > import os, select > cmd = 'python test.py' > pin, pout = os.popen2(cmd) > select.select([pout], [], [], timeout)[0] > pout.read() > > 根据文档select应该等到pout有可读取的内容(即前500个'hello')时就返回,但实 > 际情况是它要一直到test.py全部执行完毕才返回可读的内容。 > > 谁知道这段代码应该如何正确书写?代码运行在Linux下。 > > -- > HONG Yuan > > 大管家网上建材超市 > http://www.homemaster.cn > > _______________________________________________ > python-chinese list > python-chinese at lists.python.cn > http://python.cn/mailman/listinfo/python-chinese > -- I'm the one, powered by nEO
2005年06月29日 星期三 14:32
select用于socket本来就没有问题的,但对于进程间的管道好像是有问题的。 Neo Chan (netkiller) wrote: > >大同小意..改改就成..自己研究去吧. > >import select >import socket >import time > >PORT = 8037 > >TIME1970 = 2208988800L > >service = socket.socket(socket.AF_INET, socket.SOCK_STREAM) >service.bind(("", PORT)) >service.listen(1) > >print "listening on port", PORT > >while 1: > is_readable = [service] > is_writable = [] > is_error = [] > r, w, e = select.select(is_readable, is_writable, is_error, 1.0) > if r: > channel, info = service.accept() > print "connection from", info > t = int(time.time()) + TIME1970 > t = chr(t>>24&255) + chr(t>>16&255) + chr(t>>8&255) + chr(t&255) > channel.send(t) # send timestamp > channel.close() # disconnect > else: > print "still waiting" > >Neo Chan (netkiller) >Best Regards, 73! de BG7NYT >Amateur Radio Callsign: BG7NYT > >注:我这里上不了网,请不要发URL给我,如果方便请附件发给我 > > >-----Original Message----- >From: python-chinese-bounces at lists.python.cn [mailto:python-chinese-bounces at lists.python.cn] On Behalf Of Hong Yuan >Sent: Wednesday, June 29, 2005 1:52 PM >To: python-chinese at lists.python.cn >Subject: [python-chinese] 如何非阻塞地读取子进程的输出 > >我在程序中需要启动一个外部命令并读取该命令的输出。问题是这个外部命令在产 >生第一部分输出后要停顿很长时间,而我并不想等到外部命令全部结束再去读取它 >的输出,而想先得到第一部分的输出。 > >例如,假设外部程序是以下python代码: > >test.py: >import sys, time >print 'hello'*500 >sys.stdout.flush() >time.sleep(100) >print 'world'*500 > >我希望在自己的程序中设置一个timeout,读取外部进程在这个timeout时间前的所 >有输出,即前500个'hello'。我的程序是这样写的: > >import os, select >cmd = 'python test.py' >pin, pout = os.popen2(cmd) >select.select([pout], [], [], timeout)[0] >pout.read() > >根据文档select应该等到pout有可读取的内容(即前500个'hello')时就返回,但实 >际情况是它要一直到test.py全部执行完毕才返回可读的内容。 > >谁知道这段代码应该如何正确书写?代码运行在Linux下。 > >-- >HONG Yuan > >大管家网上建材超市 >http://www.homemaster.cn > >_______________________________________________ >python-chinese list >python-chinese at lists.python.cn >http://python.cn/mailman/listinfo/python-chinese > > >_______________________________________________ >python-chinese list >python-chinese at lists.python.cn >http://python.cn/mailman/listinfo/python-chinese > > -- HONG Yuan 大管家网上建材超市 http://www.homemaster.cn
2005年06月29日 星期三 15:01
问题不在于用readline还是read,无论用哪个,都会将当前进程block到外部程序 完全执行完才会继续。 可能是对管道、缓冲什么的需要有什么设置select才能有正确的返回。 nEO wrote: >你这里不应该用read >应该用readline > >2005/6/29, Hong Yuan <hongyuan at homemaster.cn>: > > >>-- >>HONG Yuan >> >>大管家网上建材超市 >>http://www.homemaster.cn >> >>_______________________________________________ >>python-chinese list >>python-chinese at lists.python.cn >>http://python.cn/mailman/listinfo/python-chinese >> >> >> > > > > >------------------------------------------------------------------------ > >_______________________________________________ >python-chinese list >python-chinese at lists.python.cn >http://python.cn/mailman/listinfo/python-chinese > > -- HONG Yuan 大管家网上建材超市 http://www.homemaster.cn
2005年06月29日 星期三 19:19
On 6/29/05, Hong Yuan <hongyuan at homemaster.cn> wrote: > 我在程序中需要启动一个外部命令并读取该命令的输出。问题是这个外部命令在产 > 生第一部分输出后要停顿很长时间,而我并不想等到外部命令全部结束再去读取它 > 的输出,而想先得到第一部分的输出。 > > 例如,假设外部程序是以下python代码: > > test.py: > import sys, time > print 'hello'*500 > sys.stdout.flush() > time.sleep(100) > print 'world'*500 > > 我希望在自己的程序中设置一个timeout,读取外部进程在这个timeout时间前的所 > 有输出,即前500个'hello'。我的程序是这样写的: > > import os, select > cmd = 'python test.py' > pin, pout = os.popen2(cmd) > select.select([pout], [], [], timeout)[0] select的作用是查看三个流的集合,发现其中的可读,可写,以及有错误报出的流。 你这里的问题,一是没有返回这个集合,所以它被当作垃圾回收了。第二select是非阻塞的,所以返回之后,它就等着执行下一句,也就是pout.read()了。这当然要等程序执行完毕才能运行。所以我觉得应该这么写: while 1 : i,o,e = select.select([pout], [], [], timeout) if i : print i[0].read() > pout.read() > > 根据文档select应该等到pout有可读取的内容(即前500个'hello')时就返回,但实 > 际情况是它要一直到test.py全部执行完毕才返回可读的内容。 > > 谁知道这段代码应该如何正确书写?代码运行在Linux下。 顺便说一句,Linux下可以,Windows下不行。Windows的select只支持socket。
2005年06月29日 星期三 19:50
你也可以继承一下StringIO,把输出重定向到这里,然后在你需要的时候抛出异常. shhgs 写道: >On 6/29/05, Hong Yuan <hongyuan at homemaster.cn> wrote: > > >>我在程序中需要启动一个外部命令并读取该命令的输出。问题是这个外部命令在产 >>生第一部分输出后要停顿很长时间,而我并不想等到外部命令全部结束再去读取它 >>的输出,而想先得到第一部分的输出。 >> >>例如,假设外部程序是以下python代码: >> >>test.py: >>import sys, time >>print 'hello'*500 >>sys.stdout.flush() >>time.sleep(100) >>print 'world'*500 >> >>我希望在自己的程序中设置一个timeout,读取外部进程在这个timeout时间前的所 >>有输出,即前500个'hello'。我的程序是这样写的: >> >>import os, select >>cmd = 'python test.py' >>pin, pout = os.popen2(cmd) >>select.select([pout], [], [], timeout)[0] >> >> > >select的作用是查看三个流的集合,发现其中的可读,可写,以及有错误报出的流。 > >你这里的问题,一是没有返回这个集合,所以它被当作垃圾回收了。第二select是非阻塞的,所以返回之后,它就等着执行下一句,也就是pout.read()了。这当然要等程序执行完毕才能运行。所以我觉得应该这么写: > >while 1 : > i,o,e = select.select([pout], [], [], timeout) > if i : > print i[0].read() > > > >>pout.read() >> >>根据文档select应该等到pout有可读取的内容(即前500个'hello')时就返回,但实 >>际情况是它要一直到test.py全部执行完毕才返回可读的内容。 >> >>谁知道这段代码应该如何正确书写?代码运行在Linux下。 >> >> > >顺便说一句,Linux下可以,Windows下不行。Windows的select只支持socket。 > > >------------------------------------------------------------------------ > >_______________________________________________ >python-chinese list >python-chinese at lists.python.cn >http://python.cn/mailman/listinfo/python-chinese > >
2005年06月30日 星期四 10:24
谢谢大家的帮助。最后下面这段代码工作得很好: import os, fcntl, select cmd = 'python test.py' timeout = 2 pin, pout = os.popen2(cmd) pout = pout.fileno() flags = fcntl.fcntl(pout, fcntl.F_GETFL) fcntl.fcntl(pout, fcntl.F_SETFL, flags | os.O_NONBLOCK) while 1: i,o,e = select.select([pout], [], [], timeout) if i : buf = os.read(pout, 1024) if buf: print buf else: break 由fcntl函数将文件设为非阻塞模式,用select来判断是否有数据可读,然后用 os.read读取当前可读的所有数据。 -- HONG Yuan 大管家网上建材超市 http://www.homemaster.cn
2005年06月30日 星期四 17:54
这段代码工作正常 但是还是没明白为什么我的那段代码你不能运行 2005/6/30, Hong Yuan <hongyuan at homemaster.cn>: > > 谢谢大家的帮助。最后下面这段代码工作得很好: > > import os, fcntl, select > > cmd = 'python test.py' > > timeout = 2 > pin, pout = os.popen2(cmd) > > pout = pout.fileno() > flags = fcntl.fcntl(pout, fcntl.F_GETFL) > fcntl.fcntl(pout, fcntl.F_SETFL, flags | os.O_NONBLOCK) > > while 1: > i,o,e = select.select([pout], [], [], timeout) > if i : > buf = os.read(pout, 1024) > if buf: > print buf > else: > break > > 由fcntl函数将文件设为非阻塞模式,用select来判断是否有数据可读,然后用 > os.read读取当前可读的所有数据。 > > -- > HONG Yuan > > 大管家网上建材超市 > http://www.homemaster.cn > > _______________________________________________ > python-chinese list > python-chinese at lists.python.cn > http://python.cn/mailman/listinfo/python-chinese > -- I'm the one, powered by nEO -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.exoweb.net/pipermail/python-chinese/attachments/20050630/d82856b3/attachment.html
Zeuux © 2025
京ICP备05028076号