Run cmd and return (status,output,parsedOutput).

    Unless dryrun is set True, cmd is run using subprocess.Popen. It
    returns the exit status from cmd, its output, and any output found
    by searching for the regular expression parseForRegEx. cmd is
    logged at the debug level.

    The parameters are:

    cmd                  The command to be executed in either a string
                         or a sequence of program arguments. If cmd is a
                         string (str or unicode), it will be executed through
                         a shell (see subprocess for a discussion of associated
                         security risks).

    printOutput          Specifies if output is written to stdout.

    exceptionOnError     Specifies if a non-zero exit status of cmd should
                         raise an Exception.

    warningOnError       Specifies whether to log a warning in case of a
                         non-zero exit status of cmd.

    parseForRegEx        If not None, search cmd output for regular expression.

    regExFlags           Any regular expression flags used with parseForRegEx.

    printOutputIfParsed  Specifies if any matches found by parseForRegEx
                         should be printed to stdout.

    printErrorsIfParsed  Specifies if any matches found by parseForRegEx
                         should be logged as error.

    exceptionIfParsed    Specifies if an Exception should be raised if
                         parseForRegEx finds any matches.

    dryrun               If set True, cmd is only logged to debug and
                         nothing is run. Returns (0,'',None) in this case.

def run(cmd, printOutput=False,
        exceptionOnError=False, warningOnError=True,
        parseForRegEx=None, regExFlags=0,
        printOutputIfParsed=False, printErrorsIfParsed=False, exceptionIfParsed=False,
        dryrun=None):
    """Run cmd and return (status,output,parsedOutput).

    Unless dryrun is set True, cmd is run using subprocess.Popen. It
    returns the exit status from cmd, its output, and any output found
    by searching for the regular expression parseForRegEx. cmd is
    logged at the debug level.

    The parameters are:

    cmd                  The command to be executed in either a string
                         or a sequence of program arguments. If cmd is a
                         string (str or unicode), it will be executed through
                         a shell (see subprocess for a discussion of associated
                         security risks).

    printOutput          Specifies if output is written to stdout.

    exceptionOnError     Specifies if a non-zero exit status of cmd should
                         raise an Exception.

    warningOnError       Specifies whether to log a warning in case of a
                         non-zero exit status of cmd.

    parseForRegEx        If not None, search cmd output for regular expression.

    regExFlags           Any regular expression flags used with parseForRegEx.

    printOutputIfParsed  Specifies if any matches found by parseForRegEx
                         should be printed to stdout.

    printErrorsIfParsed  Specifies if any matches found by parseForRegEx
                         should be logged as error.

    exceptionIfParsed    Specifies if an Exception should be raised if
                         parseForRegEx finds any matches.

    dryrun               If set True, cmd is only logged to debug and
                         nothing is run. Returns (0,'',None) in this case.
    """
    if dryrun:
        debug('would run cmd: %s' % cmd)
        return (0, '', None)
    debug('running cmd: %s' % cmd)
    outputBuffer = []
    interactive =  os.environ.get('PYTHONINSPECT',None)
    if interactive:
        del os.environ['PYTHONINSPECT']
    p = subprocess.Popen(cmd,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.STDOUT,
                         shell=isinstance(cmd, (str,unicode)),
                         universal_newlines=True)
    if interactive:
        os.environ['PYTHONINSPECT'] = interactive
    for line in iter(p.stdout.readline, ""):
        outputBuffer.append(line.strip('\n'))
        if printOutput:
            sys.stdout.write(line)
    status = p.wait()
    output = '\n'.join(outputBuffer)
    if status and exceptionOnError:
        raise Exception('Error %s running command: %s: %s' %
                        (status, cmd, output))
    if status and warningOnError:
        warning('Error %s running command: %s: %s' % (status, cmd, output))
    if parseForRegEx:
        regex = re.compile(parseForRegEx, regExFlags)
        parsedOutput = '\n'.join([s for s in outputBuffer if regex.search(s)])
    else:
        parsedOutput = None
    if printOutputIfParsed and parsedOutput and not printOutput:
        print output
    if printErrorsIfParsed and parsedOutput:
        for l in parsedOutput.strip().split('\n'):
            error('found in command output: %s' % l)
    if exceptionIfParsed and parsedOutput:
        raise Exception('Errors found in command output - please check')
    return (status, output, parsedOutput)