2012-11-27 20 views
5

Mam trochę kodu, który używa pexpect do kontrolowania procesu i niektórych wydruków w kodzie. Głównym celem (w tym pytaniu) jest, aby dane wyjściowe i wydruki były zapisywane w jakimś pliku dziennika. Problemem, który napotkałem, jest to, że linie pexpect (dane wysyłane i odbierane) mieszają się z wydrukami bez widocznej logiki. Spodziewałem się, że ciągi wydruków i dane wyjściowe pexpect zostaną zarejestrowane w kolejności, w jakiej zostały wydane.Drukuj i pexpect logowanie

Przykładowy kod jest następujący:

#!/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() 

To wyjście zawartość pliku dziennika:

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 

jest jakiś sposób, aby pexpect i wyjść wydruk sekwencyjny?


Aktualizacja: Na podstawie pexpectmanual page: „Należy jednak pamiętać, że buforowanie może wpływać na ten problem, ponieważ wejście przybywa nieprzewidywalnych kawałki”. Może to potencjalnie wpłynąć na rejestrację.

Odpowiedz

2

Jeśli możesz poczekać, aż skrypt zakończy się dla wyników, nie ustawiaj pliku dziennika dla poleceń pexpect, zapisz wyniki poleceń do zmiennych i wydrukuj wszystko na końcu.

Należy również zauważyć, że brakuje danych wyjściowych polecenia info commands. Można to naprawić, dodając jeden parametr expect() do oczekiwania na uruchomienie interpretera tclsh i usunięcie "%" z końca polecenia. Zakładałem, że to był literówka.

Zmienić funkcję głównego być:

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"            

Wyjście jest wtedy:

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               
+0

Dobry pomysł. Czy drukowanie będzie od razu działać? Powinien być wtedy kontrolowany metodą "print". Mam jedno pytanie: czy należy użyć 'p.befef + p.match + p.after'? – ilya1725

+0

Drukowanie od razu nie działa, ponieważ dane są zwracane asynchronicznie, tak jak w oryginalnym skrypcie. p.before zwraca wszystko przed dopasowanym ciągiem. Ponieważ dopasowany ciąg znaków jest monitem, wszystkie dane wyjściowe polecenia zostały już wcześniej przesłane. – Edu