Question
I have a small issue that I'm not quite sure how to solve. Here is a minimal example:
What I Have
- scan_process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- while(some_criterium):
- line = scan_process.stdout.readline()
- some_criterium = do_something(line)
- scan_process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- while(some_criterium):
- line = scan_process.stdout.readline()
- if nothing_happens_after_10s:
- break
- else:
- some_criterium = do_something(line)
How-To
One solution is to write a thread (Here is class StdThd) to constantly read from stdout and read line from that thread:
- import threading, time
- class StdThd(threading.Thread):
- def __init__(self, stdout, threadName='test'):
- super(StdThd, self).__init__(name = threadName)
- self.isStop = False
- self.stdout = stdout # stdout file object
- self.lines = [] # list to hold lines
- self.li = 0 # Line index
- self.readBuf = [] # Buffer in reading stdout
- self.autoStdout = False # Print line to stdout
- def run(self):
- while not self.isStop:
- c = self.stdout.read(1)
- if c == '':
- self.isStop = True
- break
- self.readBuf.append(c)
- if self.readBuf[-1] == '\n':
- self.lines.append(''.join(self.readBuf))
- self.readBuf = []
- if self.autoStdout:
- print self.lines[-1].rstrip('\n')
- def readline(self, timeout=5):
- r'''
- Read one line from stdout
- @param timeout(int):
- Timeout in second while reading one line from stdout.
- '''
- if self.li < len(self.lines):
- line = self.lines[self.li]
- self.li = self.li + 1
- return line
- else:
- loop = timeout * 1000 / 100; cnt = 0
- while True:
- time.sleep(0.1)
- if self.li < len(self.lines):
- line = self.lines[self.li]
- self.li = self.li + 1
- return line
- cnt = cnt + 1
- if cnt > loop:
- return None
- test.sh
- #!/bin/sh
- var=0
- while [ "$var" -lt 10 ]; do
- var=$((var+1))
- echo "This is for testing: $var"
- sleep 10
- done
Supplement
* How can I run an external command asynchronously from Python?
沒有留言:
張貼留言