'Set up subprocess and execute command
:param cmd_input: input to pass to command in STDIN
:type cmd_input: str
:param combine_output: combine STDERR into STDOUT'

def run(self):

    log.info("Running:    '%s'    [%s]", self.get_command(), self.cwd)
    self.start_time = datetime.utcnow()
    stdout = subprocess.PIPE
    stderr = subprocess.PIPE
    stdin = None
    if (self.input_data is not None):
        stdin = subprocess.PIPE
    if self.combine_output:
        stderr = subprocess.STDOUT
    environment = {}
    environment.update(self.environment)
    environment['READTHEDOCS'] = 'True'
    if (self.build_env is not None):
        environment['READTHEDOCS_VERSION'] = self.build_env.version.slug
        environment['READTHEDOCS_PROJECT'] = self.build_env.project.slug
    if ('DJANGO_SETTINGS_MODULE' in environment):
        del environment['DJANGO_SETTINGS_MODULE']
    if ('PYTHONPATH' in environment):
        del environment['PYTHONPATH']
    if (self.bin_path is not None):
        env_paths = environment.get('PATH', '').split(':')
        env_paths.insert(0, self.bin_path)
        environment['PATH'] = ':'.join(env_paths)
    try:
        proc = subprocess.Popen(self.command, shell=self.shell, cwd=self.cwd, stdin=stdin, stdout=stdout, stderr=stderr, env=environment)
        cmd_input = None
        if (self.input_data is not None):
            cmd_input = self.input_data
        if isinstance(cmd_input, six.string_types):
            cmd_input_bytes = cmd_input.encode('utf-8')
        else:
            cmd_input_bytes = cmd_input
        cmd_output = proc.communicate(input=cmd_input_bytes)
        (cmd_stdout, cmd_stderr) = cmd_output
        try:
            self.output = cmd_stdout.decode('utf-8', 'replace')
        except (TypeError, AttributeError):
            self.output = None
        try:
            self.error = cmd_stderr.decode('utf-8', 'replace')
        except (TypeError, AttributeError):
            self.error = None
        self.exit_code = proc.returncode
    except OSError:
        self.error = traceback.format_exc()
        self.output = self.error
        self.exit_code = (-1)
    finally:
        self.end_time = datetime.utcnow()
