2012-11-27 5 views
5

J'ai un peu de code qui utilise pexpect pour contrôler un processus et quelques impressions dans le code. L'objectif principal (dans cette question) est d'avoir la sortie pexpect et les impressions enregistrées dans un fichier journal. Le problème que j'ai rencontré est que les lignes pexpect (données envoyées et reçues) sont mélangées avec les impressions sans logique apparente. Je m'attendais à ce que les chaînes d'impression et les sorties pexpect soient enregistrées dans l'ordre où elles ont été émises.Journalisation d'impression et de pexpect

Exemple de code est le suivant:

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

Ceci est le contenu du fichier journal de sortie:

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 

Est-il possible de rendre la séquence des sorties pexpect et d'impression?


Mise à jour: Basé sur le pexpectmanual page: "S'il vous plaît noter, cependant, que le buffering peut affecter ce comportement, car entrée arrive en morceaux imprévisibles". Cela peut donc potentiellement affecter la journalisation.

Répondre

2

Si vous pouvez attendre la fin du script pour les résultats, ne définissez pas de fichier journal pour les commandes pexpect, enregistrez les résultats des commandes dans les variables et imprimez tout à la fin. Notez également que la sortie info commands vous manque. Cela peut être corrigé en ajoutant un fichier expect() pour attendre le début de l'interpréteur tclsh et en supprimant le '%' de la fin de la commande. J'ai supposé que c'était une faute de frappe.

Modifier la fonction principale d'être:

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"            

La sortie est alors:

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

Bonne idée. Va-t-il simplement imprimer tout de suite aussi? Il devrait ensuite être contrôlé par la méthode 'print'. Une question que j'ai est: devrait-on utiliser p.before + p.match + p.after? – ilya1725

+0

L'impression immédiate ne fonctionne pas car les données sont renvoyées de manière asynchrone, comme dans votre script d'origine. p.before retourne tout avant la chaîne correspondante. Comme la chaîne appariée est l'invite, toute la sortie de la commande est déjà arrivée avant cela. – Edu