+++ /dev/null
-#! python
-
-"""
-A small utility that provides similar functionality to the commands module, but
-allows you to get the output from multiple processes at the same time
-"""
-
-__author__ = "Greg Darke"
-
-import subprocess, fcntl, os
-from select import select
-try:
- import cStringIO as _StringIO
-except ImportError:
- import StringIO as _StringIO
-
-class CommandRunner(object):
- def __init__(self):
- self._outputs = {}
- self._processes = {}
- self._fds = []
-
- def _executeCommand(self, cmd):
- """Execute the command"""
- output = _StringIO.StringIO()
- isShell = isinstance(cmd, str)
- process = subprocess.Popen(args = cmd, shell = isShell,
- stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
-
- # Turn blocking off
- flags = fcntl.fcntl(process.stdout, fcntl.F_GETFL) | os.O_NONBLOCK
- fcntl.fcntl(process.stdout, fcntl.F_SETFL, flags)
-
- return (output, process)
-
- def executeCommand(self, cmd):
- """Executes a command, but does not return anything"""
- output, process = self._executeCommand(cmd)
- self._outputs[process.stdout] = output
- self._processes[cmd] = process
- self._fds.append(process.stdout)
-
- def _waitLoop(self):
- count = 0
- while self._fds:
- # While there are still some processes left
- inputReady, outputReady, exceptReady = \
- select(self._fds, [], self._fds)
-
- for fd in inputReady:
- data = fd.read()
- if not data:
- self._fds.remove(fd)
- continue
- self._outputs[fd].write(data)
-
- for fd in exceptReady:
- self._fds.remove(fd)
-
- def waitForCompletion(self):
- """Waits for all of the running processes to finish"""
- self._waitLoop()
-
- def getOutputs(self):
- """Returns a dictionay containing the command as the key, and a string (of the output) as the value"""
- outputs = dict((cmd, self._outputs[process.stdout].getvalue()) for cmd, process in self._processes.items())
- return outputs