SHOW:
|
|
- or go back to the newest paste.
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(): |
41 | + | def Pump(stream, category): |
42 | - | while True: |
42 | + | queue = Queue.Queue() |
43 | - | part_line = sout.peek(io.DEFAULT_BUFFER_SIZE) |
43 | + | def rdr(): |
44 | - | if len(part_line)>0: |
44 | + | while True: |
45 | - | inp.put( ('stdout', sout.read(len(part_line)) ) ) |
45 | + | buf = stream.read1(8192) |
46 | - | else: |
46 | + | if len(buf)>0: |
47 | - | return |
47 | + | queue.put( buf ) |
48 | - | def rErr(): |
48 | + | else: |
49 | - | while True: |
49 | + | queue.put( None ) |
50 | - | part_line = serr.peek(io.DEFAULT_BUFFER_SIZE) |
50 | + | return |
51 | - | if len(part_line)>0: |
51 | + | def clct(): |
52 | - | inp.put( ('stderr', serr.read(len(part_line)) ) ) |
52 | + | active = True |
53 | - | else: |
53 | + | while active: |
54 | - | return |
54 | + | r = queue.get() |
55 | - | thOut = Thread(target=rOut) |
55 | + | try: |
56 | - | thOut.setDaemon(True) |
56 | + | while True: |
57 | - | thOut.start() |
57 | + | r1 = queue.get(timeout=0.005) |
58 | - | thErr = Thread(target=rErr) |
58 | + | if r1 is None: |
59 | - | thErr.setDaemon(True) |
59 | + | active = False |
60 | - | thErr.start() |
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__() |