Не удается получить pexpect для печати данных из команды

Я постоянно работаю над тем, как ssh и анализировать данные на устройстве, выполнив команду. У меня было несколько вопросов по пути этого начинания, и мне очень помогли с вопросами, которые я задал. Сейчас я работаю с pexpect, и я не вижу много документации о том, что я делаю. По сути, мне нужно подключиться по ssh, как я уже сказал, а затем запустить команду, которая распечатает данные, а затем получить эти данные для печати на моей консоли.

Вот мой код:

import pexpect
import pxssh
import getpass

child = pexpect.spawn('ssh www.example.com')
password = getpass.getpass('password: ')
child.sendline ('foo bar')
data = (child.read_nonblocking(size=1000, timeout=100))
print data

ВЫВОД:

password:
foo bar

В команде foo bar первая строка распечатки - foo bar, поэтому мне интересно, пытается ли она напечатать эти данные, но печатает только первую строку. Я добавляю read_nonblocking(size=1000, timeout=100), пытаясь установить размер больше, и тайм-аут, чтобы данные печатались.

ОБНОВЛЕНИЕ с помощью PXSSH

Я также пытался использовать образцы pxssh для этого и получить только список команд, которые может выполнять foo. Мне нужно получить распечатку foo bar, которая является списком конфигураций. Я предполагаю, что у вас не может быть команд с пробелами? Вот код, который я пробовал:

import pxssh
import getpass
try:
    s = pxssh.pxssh()
    s.force_password = True
    hostname = raw_input('hostname: ')
    username = raw_input('username: ')
    password = getpass.getpass('password: ')
    s.login (hostname, username, password)
    s.sendline ('foo bar')  # run a command
    s.prompt()             # match the prompt
    print s.before         # print everything before the prompt.
    s.logout()
except pxssh.ExceptionPxssh, e:
    print "pxssh failed on login."
    print str(e)

Что возвращает меня в консоль:

pxssh failed on login.
could not set shell prompt
:

Session idle time out is disabled

SSH> unset PROMPT_COMMAND
   Error - Command [unset PROMPT_COMMAND] not found.
   foo [ bar | bart | ran | up
         | cmd | bee | hvac | monkey
         | selective | list | help ]
   check[v,nv,beep] [ list | help ]
   delete [ all | bee | neewb | stuff
          | up | cmd | fooconfig | root
          | app | list | hvac | monkey
          | selective | <filename> | confirmed | list | help ]
   exit [ help ]
   get [ vcf | nvcf | snmpcf | help ] [<filename>]
   verbose [ help ]
   help [ <command> | help ]
     up arrow - brings up old command lines
     down arrow - brings up newer command lines
     right arrow - moves cursor to the right
     left arrow - moves cursor to the left
     insert - inserts a space at the cursor
     delete - deletes character at the cursor
SSH> PS1='[PEXPECT]\$ '
   Error - Command [PS1='[PEXPECT]\$ '] not found.
   foo [ bar | bart | ran | up
         | cmd | bee | hvac | monkey
         | selective | list | help ]
   check[v,nv,beep] [ list | help ]
   delete [ all | bee | neewb | stuff
          | up | cmd | fooconfig | root
          | app | list | hvac | monkey
          | selective | <filename> | confirmed | list | help ]
   exit [ help ]
   get [ vcf | nvcf | snmpcf | help ] [<filename>]
   verbose [ help ]
   help [ <command> | help ]
     up arrow - brings up old command lines
     down arrow - brings up newer command lines
     right arrow - moves cursor to the right
     left arrow - moves cursor to the left
     insert - inserts a space at the cursor
     delete - deletes character at the cursor

И, как я уже упоминал, я просто пытаюсь заставить консоль распечатать конфигурацию команды foo bar. Это код, который я работал с python-exscript, прежде чем узнал, что мне нужно работать в более старой версии Python 2.4.

КОД, КОТОРЫЙ Я РАБОТАЛ В EXSCRIPT, КОТОРЫЙ МНЕ НУЖНО СДЕЛАТЬ

account = read_login()              
conn = SSH2()                       
conn.connect('example.com')     
conn.login(account)           

conn.execute('foo bar')
data = conn.response
conn.send('exit\r')               
conn.close()
print data

Любая помощь в том, как заставить этот код работать, очень ценится! Спасибо!


person tjoenz    schedule 21.01.2014    source источник
comment
Строка документации read_nonblocking говорит, что тайм-аут не делает то, что вы думаете: тайм-аут относится только к количеству времени, необходимому для чтения хотя бы одного символа. На это не влияет параметр 'size', поэтому, если вы вызываете read_nonblocking(size=100, timeout=30) и сразу доступен только один символ, то будет немедленно возвращен один символ. Он не будет ждать 30 секунд, чтобы ввести еще 99 символов.   -  person Thomas K    schedule 22.01.2014
comment
Обычный способ использования pexpect — это child.expect(x), где x — это то, что будет напечатано в конце вашего вывода (например, в следующем приглашении), а затем взять вывод из child.before.   -  person Thomas K    schedule 22.01.2014
comment
@ThomasK О, хорошо, так как же с помощью pexpect запустить команду и получить результат для печати?   -  person tjoenz    schedule 22.01.2014
comment
Я смог запустить conn.execute('foo bar') data = conn.response print data с python-exscript, что эквивалентно pexpect? Спасибо!   -  person tjoenz    schedule 22.01.2014
comment
Взгляните на примеры pxssh здесь: pexpect.readthedocs .org/en/latest/api/   -  person Thomas K    schedule 22.01.2014
comment
@ThomasK Спасибо, я тоже попробовал эти примеры, и это запустит команду foo bar и выведет на консоль ВСЕ доступные команды foo. Он не будет печатать фактическую полную конфигурацию foo bar, которую должен.   -  person tjoenz    schedule 22.01.2014
comment
pxssh пытается изменить приглашение на что-то уникальное и последовательное, что он может искать, но предполагает, что для этого он обращается к оболочке в стиле sh, а здесь, очевидно, это не так. Если вы не можете изменить оболочку в удаленной системе, вы можете установить s.auto_prompt_reset = False; s.PROMPT='SSH> ' перед вызовом s.login().   -  person Thomas K    schedule 23.01.2014
comment
@ThomasK спасибо за это, но это не работает. Я по-прежнему получаю только команды, а не ту конфигурацию, которую ищу. На этот раз без SSH>   -  person tjoenz    schedule 23.01.2014
comment
Хорошо, что я получаю обратно только один список команд, а не несколько и только эту ошибку unset PROMPT_COMMAND Error - Command [unset PROMPT_COMMAND] not found.   -  person tjoenz    schedule 23.01.2014
comment
Глядя на код, я думаю, что вам действительно нужно передать auto_prompt_reset=False в s.login(), а не устанавливать его как атрибут. Это ошибка в документах.   -  person Thomas K    schedule 23.01.2014
comment
Спасибо, но это тоже не помогло @ThomasK   -  person tjoenz    schedule 23.01.2014
comment
Можете ли вы показать мне, что произошло?   -  person Thomas K    schedule 24.01.2014


Ответы (1)


Разобрался с вопросом. мне не хватало s.prompt()

try:
    s = pxssh.pxssh(timeout=60, maxread=2000000)
    s.force_password = True
    hostname = raw_imput('hostname: ')
    username = raw_input('password: ')
    password = getpass.getpass('password: ')
    s.PROMPT= 'SSH> '
    s.login (hostname, username, password, auto_prompt_reset=False)
    s.prompt()
    s.sendline('foo bar')
    s.prompt()
    data = s.before
    print data
    s.logout()
except pxssh.ExceptionPxssh, e:
    print "pxssh failed on login."
    print str(e)
person tjoenz    schedule 28.01.2014
comment
Вам нужен только 1 или для каждой линии отправки? - person Jack; 19.07.2016