2015-04-12 5 views
6

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

Seen неожиданные поведения (с использованием pexpect V3.3 с Python 2.7.9):

  1. После выполнения следующего кода, когда я затем пытаюсь читать из буфера, иногда я вижу странное поведение, где только часть накопленных символов была очищена. Это пахнет хаосом по моей логике вниз по течению. Я предполагаю, что это связано с тем, что весь поток укладывается в спящий режим на 5 секунд, поэтому, когда он просыпается, у него нет времени на выборку полного входящего буфера перед выполнением команды read_nonblocking().

    time.sleep(5) 
    flushedStuff += child.read_nonblocking(100000, timeout=0) 
    
  2. Когда я пытаюсь использовать .expect вызова для промывки линии в неблокируемом образом, я узнал, что после исключения TIMEOUT входящего буфер не очищается. Его содержимое можно найти как ожидалось в свойстве child.before, но оно также будет проанализировано во время следующего вызова метода .expect. Так что это вообще не смывает линию! Я также заметил, что read_nonblocking() не читает из локального буфера, но читает непосредственно из строки через ОС, поэтому он не видит этого.

    try: 
        child.expect("ZzqQJjSh_Impossible_String", timeout = 5) 
    except pexpect.TIMEOUT: 
        pass 
    flushedStuff = child.before 
    

Итак, после всего этого, мое текущее решение, чтобы обеспечить надежный способ промывки линии, чтобы расширить класс икру и добавить метод, который делает следующее ... который обращается к недокументированные свойства:

class ExtendedSpawn(pexpect.spawn): 
    def flushBuffer(delay) 
     try: 
      # Greedily read in all the incoming characters 
      self.expect("ZzqQJjSh_Impossible_String", timeout = delay) 
     except pexpect.TIMEOUT: 
      pass 
     # Clear local input buffer inside the spawn Class 
     self.buffer = self.string_type() 
     return self.before 

Указанный выше метод также может использоваться для команды неблокирующего сна.

Это, кажется, слишком сложный подход к чему-то, что должно быть простым, не говоря уже о том, что я потратил пару дней на него. Есть ли лучший способ сделать это?

Спасибо!

ответ

0

Самый простой способ очистить pexpect в буфер непрерывно дочитать до данных доступен

flushedStuff = '' 
while not child.expect(r'.+', timeout=5): 
    flushedStuff += child.match.group(0) 
0

Чтобы увидеть проблему, вы можете выполнить следующий сценарий. (Сценарий оболочки отзовется числа от 1 до 10, и спать 1 секунду после каждого номера pexpect будет ждать 2 секунды для тайм-аута и печати номера видно..):

#!/usr/bin/env python 
import pexpect 
child = pexpect.spawn('/bin/sh -c "i=0; while [ $i -lt 10 ]:; do echo $((i=i+1)); sleep 1; done"') 
while True: 
    i=child.expect ([pexpect.TIMEOUT, pexpect.EOF], timeout=2) 
    if i==0: 
     print "before=%s" % child.before 
    else: 
     break 

Вывод будет выглядеть следующим образом (Мы получаем также число уже читали ранее):

before='1\r\n2\r\n' 
before='1\r\n2\r\n3\r\n4\r\n' 
before='1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n' 
before='1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n' 
before='1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n' 

для решения этой проблемы две строки могут быть добавлены к сценарию:

#!/usr/bin/env python 
import pexpect 
child = pexpect.spawn('/bin/sh -c "i=0; while [ $i -lt 10 ]:; do echo $((i=i+1)); sleep 1; done"') 
while True: 
    i=child.expect ([pexpect.TIMEOUT, pexpect.EOF], timeout=2) 
    if i==0: 
     print "before=%s" % repr(child.before) 
     if child.before: 
      child.expect (r'.+') 
    else: 
     break 

И выход будет, как и ожидалось:

before='1\r\n2\r\n' 
before='3\r\n4\r\n' 
before='5\r\n6\r\n' 
before='7\r\n8\r\n' 
before='9\r\n10\r\n'