Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!gegeweb.org!news.glorb.com!border3.nntp.dca.giganews.com!border1.nntp.dca.giganews.com!nntp.giganews.com!npeer03.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!spln!extra.newsguy.com!newsp.newsguy.com!not-for-mail From: Chris Torek Newsgroups: comp.lang.python Subject: Re: How to catch a line with Popen Date: 30 May 2011 01:02:41 GMT Organization: None of the Above Lines: 53 Message-ID: References: NNTP-Posting-Host: pdb6951b5209bbec2ba66a48d181e52589da5e74a153cb812.newsdawg.com X-Newsreader: trn 4.0-test76 (Apr 2, 2001) Originator: torek@elf.torek.net (Chris Torek) Xref: x330-a1.tempe.blueboxinc.net comp.lang.python:6602 In article TheSaint wrote: >Chris Rebert wrote: >I just suppose to elaborate the latest line, as soon it's written on the >pipe, and print some result on the screen. >Imaging something like > > p= Popen(['ping','-c40','www.google.com'], stdout=PIPE) > for line in p.stdout: > print(str(line).split()[7]) > >I'd like to see something like *time=54.4* >This is just an example, where if we remove the "-c40" on the command line, >I'd expect to read the latest line(s), until the program will be killed. In at least some versions of Python 2, file-like object "next" iterators do not "work right" with unbuffered (or line-buffered) pipe-file-objects. (This may or may not be fixed in Python 3.) A simple workaround is a little generator using readline(): def line_at_a_time(fileobj): """ Return one line at a time from a file-like object. Works around the iter behavior of pipe files in Python 2.x, e.g., instead of "for line in file" you can write "for line in line_at_a_time(file)". """ while True: line = fileobj.readline() if not line: return yield line Adding this to your sample code gives something that works for me, provided I fiddle with it to make sure that the only lines examined are those with actual ping times: p = subprocess.Popen(["ping", "-c5", "www.google.com"], stdout = subprocess.PIPE) for lineno, line in enumerate(line_at_a_time(p.stdout)): if 1 <= lineno <= 5: print line.split()[6] else: print line.rstrip('\n') p.wait() # discard final result (Presumably the enumerate() trick would not be needed in whatever you really use.) -- In-Real-Life: Chris Torek, Wind River Systems Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603 email: gmail (figure it out) http://web.torek.net/torek/index.html