Подтвердить что ты не робот

Распределение Paramiko и Pseudo-tty

Я пытаюсь использовать Paramiko для подключения к удаленному хосту и выполнения ряда подстановок текстовых файлов.

i, o, e = client.exec_command("perl -p -i -e 's/" + initial + "/" 
                              + replaced + "/g'" + conf);

Некоторые из этих команд должны выполняться как sudo, что приводит к:

sudo: извините, вы должны иметь tty для run sudo

Я могу принудительно распределить псевдо-tty с помощью ключа -t и ssh.

Можно ли сделать то же самое с помощью paramiko?

4b9b3361

Ответ 1

Я думаю, вам нужен метод invoke_shell объекта SSHClient (я бы хотел указать URL-адрес, но paramiko docs на lag.net являются тяжелыми кадрами и просто не покажут мне определенного URL-адреса для данного места в документах) - он дает вам Channel, на котором вы можете сделать exec_command и тому подобное, но что через псевдотерминал (в комплекте с типом терминала и числами строк и столбцов!), который, похоже, является тем, о чем вы просите.

Ответ 2

На самом деле это довольно просто. Просто:

stdin, stdout, stderr = client.exec_command(command,  get_pty=True)

Ответ 3

Следующий код работает для меня:

#!/usr/bin/env python
import paramiko

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('localhost',username='root',password='secret')
chan = ssh.get_transport().open_session()
chan.get_pty()
chan.exec_command('tty')
print(chan.recv(1024))

Это было просто собрано из нескольких примеров онлайн... не уверен, что это "правильный" способ.

Ответ 4

В соответствии с sudo manpage:

Опция -S (stdin) заставляет sudo считывать пароль со стандартного ввода вместо терминального устройства.                        за паролем должен следовать символ новой строки.

Вы можете написать в stdin, потому что это файловый объект с write():

import paramiko

client = paramiko.client.SSHClient()
client.set_missing_host_key_policy(paramiko.client.AutoAddPolicy())
client.connect(hostname='localhost', port=22, username='user', password='password')
stdin, stdout, stderr = client.exec_command('sudo -S aptitude update')
stdin.write('password\n')
stdin.flush()
# print the results
print stdout.read()
client.close()