def _Cmd(self, command, mode=None, merge_stderr_first=False, send=None,
           require_low_chanid=False):
    response = ''
    retries_left = 1
    while True:
      try:
        chan = self._ssh_client.get_transport().open_session()
        chan.settimeout(self.timeout_response)
        if require_low_chanid and chan.remote_chanid > _LOW_CHANID_THRESHOLD:
          # We should not be having multiple channels open. If we do,
          # close them before proceeding.
          logging.error(
              'Remote ssh channel id %d exceeded %d when opening session to '
              '%s(%s), reconnecting.',
              chan.remote_chanid, _LOW_CHANID_THRESHOLD, self.host,
              self.loopback_ipv4)
          self.Disconnect()
          self.Connect(self._username, self._password, self._ssh_keys,
                       self._enable_password)
          chan = self._ssh_client.get_transport().open_session()
        chan.exec_command(command)
        stdin = chan.makefile('wb', -1)
        stdout = chan.makefile('rb', -1)
        stderr = chan.makefile_stderr('rb', -1)
        if send is not None:
          stdin.write(send)
        stdout_data = stdout.read()
        stderr_data = stderr.read()

        # Request channel close by remote peer.
        chan.close()
        break
      except paramiko.SSHException as e:
        msg = str(e)
        logging.error('%s(%s) Cmd(%r, mode=%r): %s', self.host,
                      self.loopback_ipv4, command, mode, msg)
        raise exceptions.CmdError(msg)
      except __HOLE__:
        # This occurs when self._ssh_client becomes None after a Paramiko
        # failure. Pause momentarily, try to reconnect and loop to resend
        # the command.
        time.sleep(0.25)
        try:
          if retries_left:
            self._Connect(self._username, self._password, self._ssh_keys)
            retries_left -= 1
            continue
          else:
            raise exceptions.CmdError('Failed to exec_command after retry.')
        except paramiko.SSHException as e:
          msg = str(e)
          logging.error('%s(%s) Cmd(%r, mode=%r): %s', self.host,
                        self.loopback_ipv4, command, mode, msg)
          raise exceptions.ConnectError(msg)
      except Exception as e:
        # Paramiko may raise any exception, so catch and log it here.
        msg = '%s:%s(%s) Cmd(%r, mode=%r): %s: %s' % (
            type(e), self.host, self.loopback_ipv4, command, mode,
            e.__class__.__name__, str(e))
        logging.exception(msg)
        raise exceptions.CmdError('%s: %s' % (e.__class__.__name__, str(e)))

    # Remove stderr lines started with 'waiting for'.
    if stderr_data and not merge_stderr_first:
      out = []
      for l in stderr_data.splitlines():
        if not l.startswith('waiting for'):
          out.append(l)
      stderr_data = '\n'.join(out)

    # Marshal the response from the stdout/err channels and handle errors.
    if stderr_data and not merge_stderr_first:
      raise exceptions.CmdError(stderr_data)
    elif stdout_data:
      if merge_stderr_first and stderr_data:
        response = stderr_data
      response += stdout_data
    else:
      # Sometimes, a command (e.g., 'show system license keys') returns
      # nothing.  This can mean that the channel went away on us, and we
      # got no data back (and no error).
      if self.connected:
        logging.warn('Both STDOUT and STDERR empty after %s on %s(%s)',
                     repr(command), self.host, self.loopback_ipv4)
      else:
        raise exceptions.CmdError('Connection to %s(%s) was terminated.' %
                                  (self.host, self.loopback_ipv4))
    return response
dataset/ETHPy150Open google/capirca/tools/ldpush/paramiko_device.py/ParamikoDevice._Cmd