Paramiko ssh умирает / зависает с большим выходом

Я пытаюсь создать резервную копию сервера с помощью Paramiko и ssh для вызова команды tar. Когда количество файлов ограничено, все работает хорошо, но когда это большая папка, скрипт ждет бесконечно. Следующий тест показывает мне, что проблема связана с размером stdout.

Есть ли способ исправить это и выполнить такую ​​команду?

Корпус большой выход:

query = 'cd /;ls -lshAR -h'
chan.exec_command(query)
while not chan.recv_exit_status():
    if chan.recv_ready():
        data = chan.recv(1024)
        while data:
            print data
            data = chan.recv(1024)

    if chan.recv_stderr_ready():
        error_buff = chan.recv_stderr(1024)
        while error_buff:
            print error_buff
            error_buff = chan.recv_stderr(1024)
    exist_status = chan.recv_exit_status()
    if 0 == exist_status:
        break

Результат (не нормально - заблокировать - умереть ??)

2015-07-25 12:57:07,402 --> Query sent

Кейс малый выход:

query = 'cd /;ls -lshA -h'
chan.exec_command(query)
while not chan.recv_exit_status():
    if chan.recv_ready():
        data = chan.recv(1024)
        while data:
            print data
            data = chan.recv(1024)

    if chan.recv_stderr_ready():
        error_buff = chan.recv_stderr(1024)
        while error_buff:
            print error_buff
            error_buff = chan.recv_stderr(1024)
    exist_status = chan.recv_exit_status()
    if 0 == exist_status:
        break

Результат (все в порядке)

2015-07-25 12:55:08,205 --> Query sent
total 172K
4.0K drwxr-x---   2 root psaadm 4.0K Dec 27  2013 archives
   0 -rw-r--r--   1 root root      0 Jul  9 23:49 .autofsck
   0 -rw-r--r--   1 root root      0 Dec 27  2013 .autorelabel
4.0K dr-xr-xr-x   2 root root   4.0K Dec 23  2014 bin
2015-07-25 12:55:08,307 --> Query executed (0.10) 

person Alexis G    schedule 25.07.2015    source источник
comment
Поместите на GitHub = ›github.com/paramiko/paramiko/issues/563   -  person Alexis G    schedule 26.07.2015


Ответы (2)


Если ls -R выводит много ошибок (что вероятно, если текущий пользователь не root = ›не имеет доступа ко всем папкам), ваш код в конечном итоге зайдет в тупик.

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

Пока вы ждете завершения обычного потока вывода, чего он никогда не делает, поскольку ls ждет, пока вы прочитаете поток ошибок, чего вы никогда не делаете.

Вы должны читать оба потока параллельно (см. Запуск нескольких команд на разных серверах SSH параллельно с использованием Python Paramiko).

Или, что еще проще, используйте _5 _ объединить оба потока в один.

person Martin Prikryl    schedule 27.07.2015

прочитать данные перед проверкой статуса выхода

channel.recv_exit_status () зависает

person hustljian    schedule 23.07.2016