python - How to capture output of a shell script running in a separate process, in a wxPython TextCtrl? -


a long running shell script produces stdout , stderr, show on textctrl in gui. possible using threading , separating gui thread shell script's thread. when implement multiprocessing, hit roadblock. here's -stripped down- code:

#!/usr/bin/env python  import wx import sys, subprocess multiprocessing import process, queue queue import empty  class myframe(wx.frame):     def __init__(self, *args, **kwds):         wx.frame.__init__(self, *args, **kwds)          self.button = wx.button(self, -1 , "run")         self.output = wx.textctrl(self, -1, '', style=wx.te_multiline|\                                                       wx.te_readonly|wx.hscroll)          self.bind(wx.evt_button, self.onbutton, self.button)          sizer = wx.boxsizer(wx.vertical)         sizer.add(self.output, -1, wx.expand, 0)         sizer.add(self.button)         self.setsizerandfit(sizer)         self.centre()      def onbutton(self, event):         numtasks = 4 # total number of tasks run         numprocs = 2 # number of processors = number of parallel tasks         work_queue = queue()         in xrange(numtasks):              work_queue.put(i)         processes = [process(target=self.dowork, args=(work_queue, ))                      in range(numprocs)]         p in processes:             p.daemon = true             p.start()      def dowork(self, work_queue):         while true:             try:                 x = work_queue.get(block=false)                 self.runscript(x)             except empty:                 print "queue empty"                 break      def runscript(self, taskno):         print '## running: ', taskno         command = ['./script.sh']           proc = subprocess.popen(command, shell=true,                                           stdout=subprocess.pipe,                                           stderr=subprocess.stdout)         while true:             stdout = proc.stdout.readline()             if not stdout:                 break             #sys.stdout.flush() #no need flush, apparently embedded in multiprocessing module             self.output.appendtext(stdout.rstrip()) #this part doesn't work.  if __name__ == "__main__":     app = wx.app(0)     frame = myframe(none, title="shell2textctrl", size=(500,500))     frame.show(true)     app.mainloop() 

i've tried many solutions upon others' suggestions. among these are: using wx.callafter or wx.lib.delayedresult make gui responsive; several threading recipes (eg. wxapplication development cookbook, threadpool, others...) , have multiprocess() run separate thread; redefining sys.stdout.write write textctrl; , whatnot. none of them successfull. can please provide solution working code? can use script written somewhere here forgot who:

#!/bin/tcsh -f @ = 1 while ($i <= 20)  echo $i  @ += 1  sleep 0.2 end 

i don't know if or not, have example of using subprocess here:

http://www.blog.pythonlibrary.org/2010/06/05/python-running-ping-traceroute-and-more/

see pingip , tracertip methods. if shell script written in python, can add kind of generator ones using in article post gui. read longrunningprocess wiki article, took , made own tutorial here:

http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/


Comments