Advertisement
datacompboy

Thread-based stdout/stderr pumper

Jun 11th, 2013
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.48 KB | None | 0 0
  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 rOut():
  42.             while True:
  43.                 part_line = sout.peek(io.DEFAULT_BUFFER_SIZE)
  44.                 if len(part_line)>0:
  45.                     inp.put( ('stdout', sout.read(len(part_line)) ) )
  46.                 else:
  47.                     return
  48.         def rErr():
  49.             while True:
  50.                 part_line = serr.peek(io.DEFAULT_BUFFER_SIZE)
  51.                 if len(part_line)>0:
  52.                     inp.put( ('stderr', serr.read(len(part_line)) ) )
  53.                 else:
  54.                     return
  55.         thOut = Thread(target=rOut)
  56.         thOut.setDaemon(True)
  57.         thOut.start()
  58.         thErr = Thread(target=rErr)
  59.         thErr.setDaemon(True)
  60.         thErr.start()
  61.  
  62.         while p.poll() is None:
  63.             # App still working
  64.             try:
  65.                 chan,line = inp.get(timeout = 1.0)
  66.                 if chan=='stdout':
  67.                     print "STDOUT>>", line, "<?<"
  68.                 elif chan=='stderr':
  69.                     print " ERROR==", line, "=?="
  70.             except Queue.Empty:
  71.                 pass
  72.         print "Finish"
  73.  
  74. if __name__ == '__main__':
  75.     __main__()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement