Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Re: Capture output from stderr

Reply
Thread Tools

Re: Capture output from stderr

 
 
Grant Edwards
Guest
Posts: n/a
 
      08-06-2003
In article <(E-Mail Removed) >, klappnase wrote:

> I am trying to program a Tkinter application for linux, so I want to
> run a shell command from the gui and capture its output on the fly
> while the process is still running in order to display the progress
> messages in a toplevel window so the user may watch what is going on
> (the execution of the shell command may take a few minutes). Because
> the output is printed to stderr I thought I should use a popen2.Popen4
> instance for that, like:
>
> self.pp = popen2.Popen4("exec cmd")
>
> I tried something like
>
> def getmsg(self):
> msg = self.pp.fromchild
> newmsg = msg.read(100)
> ...(do something)...
> self.master.after(1000, self.getmsg)


I've always used a read handler for this in the past, and it worked fine.
I don't have an example handy...

--
Grant Edwards grante Yow! Like I always
at say -- nothing can beat
visi.com the BRATWURST here in
DUSSELDORF!!
 
Reply With Quote
 
 
 
 
Jeff Epler
Guest
Posts: n/a
 
      08-06-2003
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

 
Reply With Quote
 
 
 
 
Grant Edwards
Guest
Posts: n/a
 
      08-06-2003
In article <(E-Mail Removed)>, Jeff Epler wrote:

>> I've always used a read handler for this in the past, and it worked fine.
>> I don't have an example handy...


I was about to look up my example program, but you beat me to it.

> 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.


[...]

> import Tkinter, _tkinter, fcntl, os, sys
>
> 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()


I always use os.read(pf) rather than the file object's read method to gaurd
against cases where the file descriptor is readable when the file object
isn't. I don't know if that ever really happens, but it seemed to be the
safe thing to do. I suspect that your setting the file descriptor to
non-blocking accomplishes the same thing.

> if bytes == '':
> bytes = "***END OF OUTPUT***"
> t.wm_title("%s - COMPLETED - tktail" % command)
> _tkinter.deletefilehandler(p)

[...]

> _tkinter.createfilehandler(p, Tkinter.READABLE, readfunc)
> t.mainloop()


--
Grant Edwards grante Yow! I need "RONDO".
at
visi.com
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Script to capture stderr of subprocess jslowery@gmail.com Python 2 10-20-2010 07:36 PM
Capture stdout and stderr from another process Marcus Bristav Ruby 1 01-30-2008 08:02 PM
stderr capture on Windows Sard Aukary Ruby 5 08-14-2006 07:48 PM
capture stderr Simon Strandgaard Ruby 5 02-10-2004 03:47 PM
Capture stderr stdout using system call with commas? Marv Perl Misc 3 02-03-2004 03:41 PM



Advertisments