2012-11-27 6 views
5

Ho un po 'di codice che utilizza pexpect per controllare un processo e alcune stampe nel codice. L'obiettivo principale (in questa domanda) è di avere l'output pexpect e le stampe registrate in qualche file di registro. Il problema che ho riscontrato è che le linee pexpect (dati inviati e ricevuti) si confondono con le stampe senza logica apparente. Mi aspettavo che le stringhe di stampa e le uscite pexpect vengano registrate nell'ordine in cui sono state emesse.Registrazione stampa e pexpect

codice di esempio è la seguente:

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

Questa è l'uscita contenuto del file di registro:

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 

C'è un modo per rendere la sequenza pexpect e output di stampa?


Aggiornamento: Sulla base del pexpectmanual page: "Si prega di notare, tuttavia, che il buffering può influenzare questo comportamento, dal momento che arriva ingresso in blocchi imprevedibili". Quindi potrebbe potenzialmente influire sulla registrazione.

risposta

2

Se è possibile attendere fino allo scadere dello script per i risultati, non impostare un file di registro per i comandi pexpect, salvare i risultati dei comandi sulle variabili e stampare tutto alla fine.

Si noti inoltre che manca l'output del comando info commands. Questo può essere risolto aggiungendo un expect() per aspettare l'interprete tclsh per iniziare e rimuovere il '%' dalla fine del comando. Ho pensato che fosse un errore di battitura.

modificano la funzione principale di essere:

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"            

Il risultato è quindi:

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

Buona idea. Stamperà subito anche il lavoro? Dovrebbe quindi essere controllato dal metodo 'print'. Una domanda che ho è: dovrebbe essere usato 'p.before + p.match + p.after'? – ilya1725

+0

La stampa subito non funziona perché i dati vengono restituiti in modo asincrono come nel tuo script originale. p.before restituisce tutto prima della stringa corrispondente. Poiché la stringa con corrispondenza è il prompt, tutti gli output dei comandi sono già stati inviati in precedenza. – Edu