Problems with select

Alain Tesio alain at onesite.org
Tue Feb 26 19:03:30 EST 2002


On Tue, 26 Feb 2002 18:01:30 +0100, Robin Munn wrote:

> On Tue, 26 Feb 2002 04:17:30 +0100, Alain Tesio <alain at onesite.org>
> wrote:
>>Hi, I can't manage to make select work, in both 1.52 and 2.1.2
>>
>>I just want to read stderr and stdout when executing a command with
>>popen3, and I must use select, read() blocks when there is more than a
>>fixed amount of data (4 KB I think)
>>
>>The problems is that select still gives something after the end of the
>>file, or sometimes never returns anything at all.
>>
>>I create the pipes with :
>>
>>(pipe_out,pipe_in,pipe_err)=popen2.popen3(command)
>>
>>and use select like this:
>>
>>pollstatus=select.select([],[pipe_out],[pipe_err],1)
>>
>>
>>(the doc says : select(iwtd, owtd, ewtd[, timeout]) I didn't put pipe_in
>>as it's closed)
> 
> I don't think you've understood the documentation completely. The three
> lists you pass to select() are lists of objects for input, output, and
> "exceptional conditions" (which are things like out-of-band data in
> TCP/IP sockets). Here, "input" and "output" means from the point of view
> of your program: if you want to be informed when a pipe has data waiting
> for you to read, you put it in the input list.
> 
> So what I think you should be doing is:
> 
> pollstatus=select.select([pipe_out, pipe_err], [], [], 1)
> 
> Hope this helps.
> 

Hi, thanks for the explanation, but select still returns files where
there is nothing to read, after the end of the stream.

Alain


#!/usr/bin/python

import sys,select,popen2,string

def execute(command,maxiter):
	(pipe_out,pipe_in,pipe_err)=popen2.popen3(command)
	pipe_in.close()
	pipes=[pipe_out,pipe_err]
	gotsomething=1
	i=0
	while 1:
		i=i+1
		if i>maxiter:
			print "maxiter reached"
			sys.exit(0)
		pollstatus=select.select([pipe_out,pipe_err],[],[])
		print "%i select returns : " % i,pollstatus
		if not(pollstatus[0]):
			return
		for file in pollstatus[0]:
			if file.fileno()==pipe_out.fileno():
				label="out"
			elif file.fileno()==pipe_err.fileno():
				label="err"
			else:
				raise ValueError
			print "something on %s : '%s'" % (label,file.readline())

execute("cat 3lines",10)



00:59:25 alain ~/tmp $./test_select.py
1 select returns :  ([<open file '(fdopen)', mode 'r' at 0x8060450>, <open file '(fdopen)', mode 'r' at 0x808d510>], [], [])
something on out : 'first
'
something on err : ''
2 select returns :  ([<open file '(fdopen)', mode 'r' at 0x8060450>, <open file '(fdopen)', mode 'r' at 0x808d510>], [], [])
something on out : 'second
'
something on err : ''
3 select returns :  ([<open file '(fdopen)', mode 'r' at 0x8060450>, <open file '(fdopen)', mode 'r' at 0x808d510>], [], [])
something on out : 'third
'
something on err : ''
4 select returns :  ([<open file '(fdopen)', mode 'r' at 0x8060450>, <open file '(fdopen)', mode 'r' at 0x808d510>], [], [])
something on out : ''
something on err : ''
5 select returns :  ([<open file '(fdopen)', mode 'r' at 0x8060450>, <open file '(fdopen)', mode 'r' at 0x808d510>], [], [])
something on out : ''
something on err : ''
6 select returns :  ([<open file '(fdopen)', mode 'r' at 0x8060450>, <open file '(fdopen)', mode 'r' at 0x808d510>], [], [])
something on out : ''
something on err : ''
7 select returns :  ([<open file '(fdopen)', mode 'r' at 0x8060450>, <open file '(fdopen)', mode 'r' at 0x808d510>], [], [])
something on out : ''
something on err : ''
8 select returns :  ([<open file '(fdopen)', mode 'r' at 0x8060450>, <open file '(fdopen)', mode 'r' at 0x808d510>], [], [])
something on out : ''
something on err : ''
9 select returns :  ([<open file '(fdopen)', mode 'r' at 0x8060450>, <open file '(fdopen)', mode 'r' at 0x808d510>], [], [])
something on out : ''
something on err : ''
10 select returns :  ([<open file '(fdopen)', mode 'r' at 0x8060450>, <open file '(fdopen)', mode 'r' at 0x808d510>], [], [])
something on out : ''
something on err : ''
maxiter reached



More information about the Python-list mailing list