Канал Paramiko захватывает при чтении большого выхода

У меня есть код, где я выполняю команду на удаленной машине Linux и читаю вывод с помощью Paramiko. Код def выглядит следующим образом:

ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(IPAddress, username=user['username'], password=user['password']) chan = self.ssh.get_transport().open_session() chan.settimeout(10800) try: # Execute thecommand chan.exec_command(cmd) contents = StringIO.StringIO() data = chan.recv(1024) # Capturing data from chan buffer. while data: contents.write(data) data = chan.recv(1024) except socket.timeout: raise socket.timeout output = contents.getvalue() return output,chan.recv_stderr(600),chan.recv_exit_status() 

Вышеприведенный код работает для небольших выходов, но он застревает для больших выходов.

  • Как использовать регистрацию paramiko?
  • Есть ли простой способ избавиться от ненужных значений, которые появляются, когда вы используете SSH с помощью библиотеки Python в Paramiko и извлекаете вывод из CLI удаленной машины?
  • Python: как можно удаленно от моего локального компьютера до remoteA до remoteb к удаленному c с помощью Paramiko
  • python paramiko ssh
  • Парамико: Ошибка при чтении протокола SSH
  • Автоматизация подключения ssh и выполнение программы с помощью Python's Paramiko
  • Есть ли проблема с буфером здесь?

  • Как запустить код Python на SublimeREPL
  • Pyplot pcolormesh запутался, когда альфа не 1
  • запись большого количества данных в stdin
  • как изменить переменную системного пути в скрипте python?
  • Получение значения атрибутов href во всех тегах <a> в html-файле с помощью Python
  • Если вы всегда предпочитаете xrange () по диапазону ()?
  • 5 Solutions collect form web for “Канал Paramiko захватывает при чтении большого выхода”

    я не вижу проблем, связанных с каналом stdout, но я не уверен в том, как вы обрабатываете stderr. Можете ли вы подтвердить, что это не захват stderr, который вызывает проблему? Я попробую ваш код и дам вам знать.

    Обновление: когда команда, которую вы выполняете, дает много сообщений в STDERR, ваш код замерзает. Я не уверен, почему, но recv_stderr(600) может быть причиной. Таким образом, поток ошибок захвата будет таким же, как и стандартный вывод. что-то вроде,

     contents_err = StringIO.StringIO() data_err = chan.recv_stderr(1024) while data_err: contents_err.write(data_err) data_err = chan.recv_stderr(1024) 

    вы можете сначала попробовать и изменить recv_stderr(600) на recv_stderr(1024) или выше.

    Я отправляю окончательный код, который работал с вкладками от Брюса Уэйна (:))

     ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(IPAddress, username=user['username'], password=user['password']) chan = self.ssh.get_transport().open_session() chan.settimeout(10800) try: # Execute the given command chan.exec_command(cmd) # To capture Data. Need to read the entire buffer to capture output contents = StringIO.StringIO() error = StringIO.StringIO() while not chan.exit_status_ready(): if chan.recv_ready(): data = chan.recv(1024) #print "Indside stdout" while data: contents.write(data) data = chan.recv(1024) if chan.recv_stderr_ready(): error_buff = chan.recv_stderr(1024) while error_buff: error.write(error_buff) error_buff = chan.recv_stderr(1024) exit_status = chan.recv_exit_status() except socket.timeout: raise socket.timeout output = contents.getvalue() error_value = error.getvalue() return output, error_value, exit_status 

    На самом деле, я думаю, что все вышеперечисленные ответы не могут решить настоящую проблему:

    если удаленная программа производит большое количество выходных данных stderr, тогда

     stdout.readlines() stderr.readlines() 

    будет вечно вешать. несмотря на то что

     stderr.readlines() stdout.readlines() 

    разрешит этот случай, но он потерпит неудачу, если удаленная программа выдаст большое количество выходных данных stdout .

    У меня пока нет решения …

    Это проще, если вы используете представление высокого уровня открытой сессии ssh. Поскольку вы уже используете ssh-client для открытия своего канала, вы можете просто запустить свою команду оттуда и избежать дополнительной работы.

     ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(IPAddress, username=user['username'], password=user['password']) stdin, stdout, stderr = ssh.exec_command(cmd) for line in stdout.readlines(): print line for line in stderr.readlines(): print line 

    Вам нужно будет вернуться и прочитать из этих файлов снова, если после этого вы получите дополнительные данные.

    Чтобы команды paramiko ведут себя как subprocess.call, вы можете использовать этот кусок кода (проверенный с помощью python-3.5 и paramiko-2.1.1):

     #!/usr/bin/env /usr/bin/python3 import os import sys from paramiko import SSHClient, AutoAddPolicy from socket import getfqdn class SecureSHell(object): reuser = os.environ['USER'] remote = '' def __init__(self, *args, **kwargs): for arg in args: if hasattr(self, arg): setattr(self, arg, True) for (key, val) in kwargs.items(): if hasattr(self, key): setattr(self, key, val) @staticmethod def _ssh_(remote, reuser, port=22): if '@' in remote: _reuser, remote = remote.split('@') _fqdn = getfqdn(remote) remote = _fqdn if _fqdn else remote ssh = SSHClient() ssh.set_missing_host_key_policy(AutoAddPolicy()) ssh.connect(remote, int(port), username=reuser) return ssh def call(self, cmd, remote=None, reuser=None): remote = remote if remote else self.remote reuser = reuser if reuser else self.reuser ssh = self._ssh_(remote, reuser) chn = ssh.get_transport().open_session() chn.settimeout(10800) chn.exec_command(cmd) while not chn.exit_status_ready(): if chn.recv_ready(): och = chn.recv(1024) while och: sys.stdout.write(och.decode()) och = chn.recv(1024) if chn.recv_stderr_ready(): ech = chn.recv_stderr(1024) while ech: sys.stderr.write(och.decode()) ech = chn.recv_stderr(1024) return int(chn.recv_exit_status()) ssh = SecureSHell(remote='example.com', user='d0n') ssh.call('find') 
    Python - лучший язык программирования в мире.