использование python для полного подключения к серверу по ssh

#python #ssh #subprocess

Вопрос:

Я пытался автоматизировать ssh-вход на свой сервер, однако не могу найти способ полностью автоматизировать этот процесс. Чтобы быть точным, обойти этот ввод было непросто: пароль root@example:

Мой код:

 import subprocess
import time

server_ip = 'server'
pwd = b'password'


p = subprocess.Popen(['ssh', 'root@{}'.format(server_ip)],
                    stdin=subprocess.PIPE,  stdout=subprocess.PIPE)

if p == "root@example's password: ":
    p.communicate(input= "{}".format(pwd))
else:
    time.sleep(2)
    if p == "root@example's password: ":
        p.communicate(input= "{}".format(pwd))
    else:
        pass
 

Что он возвращает:

 Pseudo-terminal will not be allocated because stdin is not a terminal.
root@example's password: 
user@computer ~ % Permission denied, please try again.
root@example's password: 
Permission denied, please try again.
root@example's password: 
root@example: Permission denied (publickey,password).
I know my code is very scuffed but it is the furthest I've got to getting in and submitting the password entry request.
 

Любая помощь будет признательна!

Комментарии:

1. вы можете использовать paramiko для удаленного выполнения команды с python через ssh-соединение. это помогло бы?

2. Также стоит оформить заказ fabfile.org

Ответ №1:

if p == "root@example's password: ": никогда не может быть истинным; p это subprocess.Popen объект, а не строка.

Вы можете получить строку, прочитав стандартный вывод объекта, но , конечно, ssh выводит на экран сообщение с tty приглашением, поэтому вы не можете легко захватить его из Python.

Обратите также внимание , что без encoding аргумента ключевого слова или text=True вы не можете отправлять или получать строки; вывод, который вы получите, будет строкой b'...' байтов, которую нельзя сравнить с обычной строкой.

… Но даже если вам удалось решить эти проблемы, переход оттуда к полностью работающему интерактивному сеансу SSH все еще довольно далеко. Я бы определенно рекомендовал вам попробовать pexpect или Парамико вместо того, чтобы запускать свой собственный, особенно если вы новичок в Python.

По касательной, else: pass это совершенно не нужно; в первую очередь нет причин добавлять else: блок, если у вас нет ничего полезного, чтобы поместить в него. И как "{}".format(pwd) действительно сложный способ написать то , что может быть проще выражено как pwd , или str(pwd) если это еще не строка.