Я пытаюсь работать с gdb удаленно, используя pexpect. Это мой текущий код:
child = pexpect.spawn("ssh [email protected] \"gdb\"")
child.logfile = sys.stdout
child.expect("password:")
child.sendline("xxxx")
child.expect("(gdb)")
child.sendline("attach 9813")
child.expect("(gdb)")
child.sendline("info registers")
child.expect("(gdb)")
child.sendcontrol('c')
И это часть вывода моей консоли:
(...)
GNU gdb (GDB) 7.4.1-debian
(...)
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) attach 9813
info registers
test@test-virtual-machine:~$
Хотя я ожидаю что-то вроде этого:
(...)
GNU gdb (GDB) 7.4.1-debian
(...)
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) attach 9813
<Attaching...>
(gdb) info registers
<Registers info displayed...>
(gdb) <Ctrl+C is done>
test@test-virtual-machine:~$
Итак, проблема, похоже, заключается в том, что после сопоставления первой (gdb)
и отправки первой команды attach 9813
pexpect не ожидает, что вторая строка (gdb)
отправит новую команду info registers
. Он снова видит первую (gdb)
, сопоставляет ее и просто отправляет вторую команду, не дожидаясь выполнения первой (пока мы не подключимся к нужному процессу).
Как я могу заставить его анализировать только следующий вывод? Без повторного сопоставления предыдущего вывода? Я видел такой пример для ftp-сервера:
child = pexpect.spawn('ftp ftp.openbsd.org')
child.expect('(?i)name .*: ')
child.sendline('anonymous')
child.expect('(?i)password')
child.sendline('[email protected]')
child.expect('ftp> ')
child.sendline('cd /pub/OpenBSD/3.7/packages/i386')
child.expect('ftp> ')
child.sendline('bin')
child.expect('ftp> ')
child.sendline('prompt')
Как я понимаю, здесь pexpect успевает отреагировать на ftp>
в нужном порядке и отправляет команды последовательно. Мой код кажется похожим.
Я также пытался сбросить стандартный вывод, это не сработало.
expect()
на самом деле рассматривает свой аргумент как шаблон регулярного выражения, а не простую строку, поэтому ваш поиск подсказки в первый раз, вероятно, совпадает сGNU gdb (GDB) 7.4.1-debian
, а во второй раз - с URL-адресом отчета об ошибке или с чем-то в пропущенной части. Попробуйте использоватьexpect_exact()
для простого сопоставления строк. - person Thomas K   schedule 22.07.2014expect_exact()
не помогло. Но я также попробовал expect(((gdb).*){2}) для моего второго cmdinfo registers
, и, к сожалению, он работает, поэтому он соответствует 2(gdb)
. Но такое решение — крайняя мера. Знаете ли вы, имеет ли оно какое-либо отношение к размеру окна поиска? Пробовал назначать0, 1, 2
, не помогает, и похоже я не понимаю механизма. - person primavera314   schedule 23.07.2014expect()
наexpect_exact()
, хотя это кажется более справедливым (за исключением регулярного выражения, которое я показал выше). - person primavera314   schedule 23.07.2014(...)
) содержать(gdb)
? Размер окна поиска здесь не должен иметь значения. - person Thomas K   schedule 23.07.2014expect
полностью анализирует представленный буфер каждый раз с самого начала. Тогда я не очень понимаю, как работает примерftp
. Так или иначе, мне пришлосьexpect
использовать специальные ключевые слова в выводе выполнения команд, только так я пока могу понять, что выполнение завершено. Если я придумаю что-то лучше, я опубликую это. Спасибо за помощь! - person primavera314   schedule 25.07.2014