Запуск интерактивных команд в Paramiko - PullRequest
36 голосов
/ 17 декабря 2008

Я пытаюсь запустить интерактивную команду через paramiko. Выполнение cmd пытается запросить пароль, но я не знаю, как предоставить пароль через exec_command paramiko, и выполнение зависает. Есть ли способ отправить значения в терминал, если выполнение cmd ожидает ввода в интерактивном режиме?

ssh = paramiko.SSHClient()
ssh.connect(server, username=username, password=password)
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command("psql -U factory -d factory -f /tmp/data.sql")

Кто-нибудь знает, как это можно адресовать? Спасибо.

Ответы [ 6 ]

29 голосов
/ 17 декабря 2008

Полный дистрибутив Paramiko поставляется с большим количеством хороших демонстраций .

В подкаталоге demos demo.py и interactive.py имеют полные интерактивные примеры TTY, которые, вероятно, будут излишними для вашей ситуации.

В приведенном выше примере ssh_stdin действует как стандартный объект файла Python, поэтому ssh_stdin.write должен работать, пока канал все еще открыт.

Мне никогда не приходилось писать в stdin, но в документах предполагается, что канал закрывается сразу после выхода из команды, поэтому использование стандартного метода stdin.write для отправки пароля, вероятно, не сработает. На самом канале есть команды paramiko более низкого уровня, которые дают вам больше контроля - посмотрите, как метод SSHClient.exec_command реализован для всех подробностей.

10 голосов
/ 14 сентября 2012

У меня возникла та же проблема при попытке сделать интерактивный сеанс SSH с использованием SSH , форка Paramiko.

Я покопался и нашел эту статью:

Обновленная ссылка (последняя версия перед тем, как ссылка сгенерировала 404): http://web.archive.org/web/20170912043432/http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/

Чтобы продолжить ваш пример, вы можете сделать

ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command("psql -U factory -d factory -f /tmp/data.sql")
ssh_stdin.write('password\n')
ssh_stdin.flush()
output = ssh_stdout.read()

В статье более подробно описывается полностью интерактивная оболочка вокруг exec_command. Я нашел это намного проще в использовании, чем примеры в источнике.

Исходная ссылка : http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/

4 голосов
/ 22 июня 2010

Вам нужен Pexpect, чтобы получить лучшее из обоих миров (ожидайте и ssh wrappers).

3 голосов
/ 28 сентября 2016
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(server_IP,22,username, password)


stdin, stdout, stderr = ssh.exec_command('/Users/lteue/Downloads/uecontrol-CXC_173_6456-R32A01/uecontrol.sh -host localhost ')
alldata = ""
while not stdout.channel.exit_status_ready():
   solo_line = ""        
   # Print stdout data when available
   if stdout.channel.recv_ready():
      # Retrieve the first 1024 bytes
      solo_line = stdout.channel.recv(1024) 
      alldata += solo_line
   if(cmp(solo_line,'uec> ') ==0 ):    #Change Conditionals to your code here  
     if num_of_input == 0 :
      data_buffer = ""    
      for cmd in commandList :
       #print cmd
       stdin.channel.send(cmd)        # send input commmand 1
      num_of_input += 1
     if num_of_input == 1 :
      stdin.channel.send('q \n')      # send input commmand 2 , in my code is exit the interactive session, the connect will close.
      num_of_input += 1 
print alldata
ssh.close()              

Почему stdout.read () будет зависать, если использовать напрямую без проверки stdout.channel.recv_ready (): в то время как stdout.channel.exit_status_ready ():

В моем случае, после запуска команды на удаленном сервере, сеанс ожидает ввода пользователя, после ввода 'q' соединение будет закрыто. Но перед вводом 'q' stdout.read () будет ожидать EOF, кажется, этот меторд не работает, если буфер больше.

  • Я пробовал stdout.read (1) в то время, как работает
    Я попытался stdout.readline () в то время как, он также работает.
    stdin, stdout, stderr = ssh.exec_command ('/ Users / lteue / Downloads / uecontrol')
    stdout.read () будет зависать
3 голосов
/ 17 декабря 2008

Я не знаком с парамико, но это может сработать:

ssh_stdin.write('input value')
ssh_stdin.flush()

Для получения информации о стандартном вводе:

http://docs.python.org/library/sys.html?highlight=stdin#sys.stdin

0 голосов
/ 30 мая 2016

Взгляните на пример и сделайте аналогичным образом

(от http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/):

    ssh.connect('127.0.0.1', username='jesse', 
        password='lol')
    stdin, stdout, stderr = ssh.exec_command(
        "sudo dmesg")
    stdin.write('lol\n')
    stdin.flush()
    data = stdout.read.splitlines()
    for line in data:
        if line.split(':')[0] == 'AirPort':
            print line
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...