Advertisement
datacompboy

Thread-based stdout/stderr pumper

Jun 11th, 2013
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/python
  2. #
  3. # Runner with stdout/stderr catcher
  4. #
  5. from sys import argv
  6. from subprocess import Popen, PIPE
  7. import os, io
  8. from threading import Thread
  9. import Queue
  10. def __main__():
  11.     if (len(argv) > 1) and (argv[-1] == "-sub-"):
  12.         import time, sys
  13.         print "Application runned!"
  14.         time.sleep(2)
  15.         print "Slept 2 second"
  16.         time.sleep(1)
  17.         print "Slept 1 additional second",
  18.         time.sleep(2)
  19.         sys.stderr.write("Stderr output after 5 seconds")
  20.         print "Eol on stdin"
  21.         sys.stderr.write("Eol on stderr\n")
  22.         time.sleep(1)
  23.         print "Wow, we have end of work!",
  24.     else:
  25.         os.environ["PYTHONUNBUFFERED"]="1"
  26.         try:
  27.             p = Popen( argv + ["-sub-"],
  28.                        bufsize=0, # line-buffered
  29.                        stdin=PIPE, stdout=PIPE, stderr=PIPE )
  30.         except WindowsError, W:
  31.             if W.winerror==193:
  32.                 p = Popen( argv + ["-sub-"],
  33.                            shell=True, # Try to run via shell
  34.                            bufsize=0, # line-buffered
  35.                            stdin=PIPE, stdout=PIPE, stderr=PIPE )
  36.             else:
  37.                 raise
  38.         inp = Queue.Queue()
  39.         sout = io.open(p.stdout.fileno(), 'rb', closefd=False)
  40.         serr = io.open(p.stderr.fileno(), 'rb', closefd=False)
  41.         def Pump(stream, category):
  42.             queue = Queue.Queue()
  43.             def rdr():
  44.                 while True:
  45.                     buf = stream.read1(8192)
  46.                     if len(buf)>0:
  47.                         queue.put( buf )
  48.                     else:
  49.                         queue.put( None )
  50.                         return
  51.             def clct():
  52.                 active = True
  53.                 while active:
  54.                     r = queue.get()
  55.                     try:
  56.                         while True:
  57.                             r1 = queue.get(timeout=0.005)
  58.                             if r1 is None:
  59.                                 active = False
  60.                                 break
  61.                             else:
  62.                                 r += r1
  63.                     except Queue.Empty:
  64.                         pass
  65.                     inp.put( (category, r) )
  66.             for tgt in [rdr, clct]:
  67.                 th = Thread(target=tgt)
  68.                 th.setDaemon(True)
  69.                 th.start()
  70.         Pump(sout, 'stdout')
  71.         Pump(serr, 'stderr')
  72.  
  73.         while p.poll() is None:
  74.             # App still working
  75.             try:
  76.                 chan,line = inp.get(timeout = 1.0)
  77.                 if chan=='stdout':
  78.                     print "STDOUT>>", line, "<?<"
  79.                 elif chan=='stderr':
  80.                     print " ERROR==", line, "=?="
  81.             except Queue.Empty:
  82.                 pass
  83.         print "Finish"
  84.  
  85. if __name__ == '__main__':
  86.     __main__()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement