Печать и ожидание регистрации

У меня есть немного кода, который использует pexpect для управления процессом и некоторыми отпечатками в коде. Основная цель (в этом вопросе) состоит в том, чтобы вывод pexpect и печать регистрировались в каком-либо файле журнала. Проблема, с которой я столкнулся, заключается в том, что строки pexpect (отправленные и полученные данные) смешиваются с отпечатками без какой-либо очевидной логики. Я ожидал, что строки печати и выходные данные pexpect будут регистрироваться в том порядке, в котором они были выпущены.

Пример кода следующий:

#!/usr/bin/env python

import pexpect
import time, sys, os

###############################################################################
# Subclass of file object to avoid recording extensive whitespace characters
class CleanFile(file):
    def write (self, text):
        # Remove the whitespaces
        out_text = ''
        # process the backspace properly
        bline = ''
        for c in text:
            if (ord(c) == 0x8):
                if (len(bline) == 0):
                    # Move the file pointer.
                    file.seek(self, -1, os.SEEK_CUR);
                else:
                    bline = bline[:-1]
            else:
                bline += c

        # remove whitespaces from inside a line
        out_text += ''.join(c for c in bline if (ord(c) >= 32 or ord(c) == 10));

        file.write(self, out_text);

###############################################################################
def main():
    fout = CleanFile ("options.log_file.log", 'w')

    sys.stdout = os.fdopen (sys.stdout.fileno(), 'w', 0)
    os.dup2 (fout.fileno(), sys.stdout.fileno());

    p = pexpect.spawn ('tclsh')
    p.logfile = fout

    print "Got into tclsh."
    p.sendline('ls');
    p.expect (['%',pexpect.EOF])

    p.sendline('info tclversion');
    p.expect (['%',pexpect.EOF])

    print "Got the version\n"

    p.sendline('info commands %');
    p.expect (['%',pexpect.EOF])

    p.sendline('exit');

    print 'Ended session'

###############################################################################
if __name__ == "__main__":
    main()

Это содержимое выходного файла журнала:

Got into tclsh.
ls
% lsinfo tclversion

log  options.log_file.log  pexpect_test.py  runtests.py  runtests_steinway.py
% info tclversionGot the version

info commands %

8.4
% info commands %exit
Ended session

Есть ли способ сделать вывод pexpect и вывод последовательным?


Обновление: на основе pexpect страницы руководства: " Обратите внимание, однако, что буферизация может повлиять на это поведение, поскольку ввод поступает непредсказуемыми порциями». Таким образом, это может потенциально повлиять на ведение журнала.


person ilya1725    schedule 27.11.2012    source источник


Ответы (1)


Если вы можете дождаться завершения сценария для получения результатов, не устанавливайте файл журнала для команд pexpect, сохраняйте результаты команд в переменные и печатайте все в конце.

Также обратите внимание, что вам не хватает вывода команды info commands. Это можно исправить, добавив одну функцию expect() для ожидания запуска интерпретатора tclsh и удалив «%» в конце команды. Я предположил, что это опечатка.

Измените основную функцию, чтобы она была:

def main():                                                          
    fout = CleanFile ("options.log_file.log", 'w')                   

    sys.stdout = os.fdopen (sys.stdout.fileno(), 'w', 0)             
    os.dup2 (fout.fileno(), sys.stdout.fileno());                    

    p = pexpect.spawn ('tclsh')                                      
    p.expect (['%',pexpect.EOF])                                     

    p.sendline('ls');                                                
    p.expect (['%',pexpect.EOF])                                     
    ls = p.before                                                    

    p.sendline('info tclversion');                                   
    p.expect (['%',pexpect.EOF])                                     
    tclversion = p.before                                            

    p.sendline('info commands');                                     
    p.expect (['%',pexpect.EOF])                                     
    commands = p.before                                              

    p.sendline('exit');                                              
    p.close()                                                        

    print "Got into tclsh."                                          
    print ls                                                         
    print tclversion                                                 
    print "Got the version\n"                                        
    print commands                                                   
    print "Ended session"                                            

Результат тогда:

Got into tclsh.                                                      
 ls                                                                  
options.log_file.log  pexpect_test.py                                

 info tclversion                                                     
8.5                                                                  

Got the version                                                      

 info commands                                           
tell socket subst open eof pwd glob list pid exec auto_load_index time unknown  
eval lassign lrange fblocked lsearch auto_import gets case lappend proc break v 
ariable llength auto_execok return linsert error catch clock info split array i 
f fconfigure concat join lreplace source fcopy global switch auto_qualify updat 
e close cd for auto_load file append lreverse format unload read package set bi 
nary namespace scan apply trace seek while chan flush after vwait dict continue 
 uplevel foreach lset rename fileevent regexp lrepeat upvar encoding expr unset 
 load regsub history interp exit puts incr lindex lsort tclLog string           

Ended session                                                        
person Edu    schedule 29.11.2012
comment
Хорошая идея. Будет ли работать только печать сразу? Затем он должен контролироваться методом print. У меня есть один вопрос: следует ли использовать p.before + p.match + p.after? - person ilya1725; 01.12.2012
comment
Немедленная печать не работает, поскольку данные возвращаются асинхронно, как и в исходном сценарии. p.before возвращает все до совпадающей строки. Поскольку совпадающая строка является подсказкой, все выходные данные команды уже были получены до этого. - person Edu; 01.12.2012