Рекомендовать способ взаимодействия с сеансом S SH в Python - PullRequest
0 голосов
/ 15 марта 2020

Я работаю над небольшой python программой для ускорения управления различными серверами Raspberry Pi через S SH. Это все сделано, но с одной стороны. Взаимодействие с сеансом S SH не работает так, как я хочу.

Я могу взаимодействовать с командой, но некоторые команды (особенно с возможностью полного обновления), которые задают или могут задавать вопросы, пока они выполняются, не работают. Поэтому, когда он достигает точки, где он спрашивает, хотите ли вы продолжить [Y / n], он падает. Я верю, что это потому, что apt не может читать с stdin, поэтому прерывает работу.

Я знаю, что мог бы запустить команду apt с флагом -y и обойти вопрос, но в идеале я хотел бы иметь возможность захватывать запросы и запрашивать ввод данных у пользователя. Я использую Paramiko для управления своими сессиями S SH, и я собираю стандартный вывод и передаю его в функцию поиска для поиска таких вещей, как [Y / n], и если он находит это, то перенаправляет пользователя в приглашение ввода, которое работает, но потому что нет никакого стандартного ввода, когда apt задает вопрос, который он прерывает, и когда я отправляю свой пользовательский ввод обратно в сеанс S SH, я получаю ошибку закрытия сокета.

Я искал альтернативы или способы обойти эту проблему, но кроме того, что fabri c упоминается как альтернатива paramiko, я не вижу там много других вариантов. Кто-нибудь знает какие-либо альтернативы, которые я могу попытаться paramiko. Я не думаю, что fabri c будет работать для меня, учитывая, что он основан на paramiko, поэтому я предполагаю, что я столкнулся с той же ошибкой. Я был бы признателен за любые рекомендации или указания, если есть другие части Paramiko, которые я могу попробовать (я придерживался использования exec_command). Я пробовал каналы, которые работают до определенного момента, но я не думаю, что сохранение сеанса S SH открытым - это проблема, которую, я думаю, мне нужно как-то, чтобы stdin был открыт / доступен для команды apt на удаленной машине, чтобы он не прервать команду.

В ту минуту, когда у меня есть лучшая идея, чтобы обойти это, это запустить команду, чтобы она потенциально могла прервать поиск в stdout соответствующих фраз, а затем снова запустить команду после предоставления пользователю возможности установить свои входные данные. и передать весь лот в stdin?

РЕДАКТИРОВАТЬ:

Моя программа в шагах:

  1. войти на удаленный хост
  2. выдать команду
  3. используйте команду .find для проверки использования 'sudo'
  4. , если присутствует sudo, дополнительно отправьте пароль пользователя на stdin вместе с командой
  5. прочитайте stdout для проверки ключевых слов / фраз, таких как '[Y / n]', которые присутствуют, когда у пользователя запрашивается ввод при выполнении команды
  6. , если ключевое слово найдено, спросите пользователя о его вводе, который может затем отправьте обратно на стандартный ввод, чтобы продолжить выполнение команды.

На этапах 5 и 6 происходит сбой и происходит возврат с ошибкой закрытия сокета. Смотря в онлайн, я не думаю, что проблема связана с paramiko как таковым, а с командой, запущенной на удаленном хосте. В моем случае sudo подходит для полного обновления.

Когда я запускаю эту команду, она запускается до точки «Вы хотите продолжить», указывающей на автоматическое прерывание, я полагаю, что проблема заключается в том, что в этом месте в stdin ничего нет (вот что я » я запрашиваю у пользователя) Apt автоматически прерывает

Это часть моего кода, где я выполняю команды:

            admin = issue_cmd.find('sudo')

        connect.connect(ip_addr, port, uname, passwd)
        stdin, stdout, stderr = connect.exec_command(issue_cmd, get_pty=True)

        if admin != -1:
            print('Sudo detected. Attempting to elevate privileges...')
            stdin.write(passwd + '\n')
            stdin.flush()
        else:
            continue

        output = stdout.read()
        search = str(output).find('[Y/n]')

        if search != -1:
            resp = input(': ')
            print(resp)
            stdin.write(resp + '\n')
            stdin.flush()
        else:
             pass

        print(stdout.read().decode('utf-8').strip("\n"))
        print(stderr.read().decode('utf-8').strip("\n"))

        connect.close()

и вот сообщение об ошибке Я вижу:

OSError: Socket is closed
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...