Capture output from stderr

klappnase klappnase at web.de
Wed Aug 6 05:57:51 EDT 2003


Jeff Epler <jepler at unpythonic.net> wrote in message news:<mailman.1060136229.29900.python-list at python.org>...
> On Wed, Aug 06, 2003 at 12:30:13AM +0000, Grant Edwards wrote:
> > I've always used a read handler for this in the past, and it worked fine.
> > I don't have an example handy...
> 
> ... this is found at _tkinter.createfilehandler() or
> Tkinter.createfilehandler() [though this didn't work for me!], doesn't
> exist on Windows (AFAIK), and seems to be undocumented in pydoc.  I think
> they're a wrapper on Tcl_CreateFileHandler, which has a manpage.
> 
> Here's a little program I just put together, it shows the
> output from a command in a scrolling text area, using popen and
> _tkinter.createfilehandler.  It doesn't do anything in particular about
> stderr, but that's a matter of switching to popen4 or a friend  (Another
> way, on systems that use /bin/sh as their shell, is to use
> 'exec 2>&1; actual command' as the popen argument).  Other niceties need
> to be observed, like making the Text and refuse keybooard
> focus and be non-editable ...
> 
> On my system, a good command that takes some time to execute and only
> produces a few hundred lines of output is
> 	$ python tktail.py rpm -qa
> ... but that'll only work on systems with rpm.  Something that would
> work on more systems would be
> 	$ python tktail.py "for i in /*; do echo $i; sleep 1; done"
> 
> # The following code is placed in the public domain
> import Tkinter, _tkinter, fcntl, os, sys
> 
> t = Tkinter.Tk()
> tx = Tkinter.Text(wrap="char")
> tx.pack(side="left", expand=1, fill="both")
> s = Tkinter.Scrollbar(orient="v", command=tx.yview)
> s.pack(side="left", fill="y")
> tx.configure(yscrollcommand=s.set)
> 
> command = " ".join(sys.argv[1:])
> t.wm_title("%s - tktail" % command)
> p = os.popen(command, "r")
> pf = p.fileno()
> 
> # Make reads from the popen'd command nonblocking
> # (so read returns the bytes available without waiting)
> fcntl.fcntl(pf, fcntl.F_SETFL, os.O_NONBLOCK)
> 
> 
> def readfunc(fileobj, event_type):
> 	bytes = p.read()
> 	if bytes == '':
> 		bytes = "***END OF OUTPUT***"
> 		t.wm_title("%s - COMPLETED - tktail" % command)
> 		_tkinter.deletefilehandler(p)
> 
> 	# bbox is a true value if the specified location is visible
> 	b = tx.bbox('end - 1l')
> 
> 	tx.insert('end', bytes)
> 
> 	# If the bottom line was visible before, scroll to the
> 	# new bottom.
> 	if b: tx.see('end')
> 	
> _tkinter.createfilehandler(p, Tkinter.READABLE, readfunc)
> t.mainloop()
> 
> Jeff


Wow, it works!
Thank you so much for your help

Best regards

Michael




More information about the Python-list mailing list