2012-11-27 8 views
5

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と印刷出力シーケンシャルを作るためにどのような方法がありますか?


更新pexpectmanual pageに基づいて:「 入力は予測できないチャンクで到着するので、バッファリングがこの動作に影響を与えることができること、しかし、注意してください」。したがって、ロギングに影響する可能性があります。

答えて

2

結果が出るまでスクリプトが終了するまで待つことができる場合は、pexpectコマンドのログファイルを設定したり、コマンドの結果を変数に保存したり、最後にすべてを出力したりしないでください。

info commandsコマンドの出力が欠落していることにも注意してください。これは、tclshインタープリタがコマンドの最後から '%'を開始して削除するのを待つためのexpect()を1つ追加することで修正できます。私はそれが誤字だと思った。

する主な機能を変更します。

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

良いアイデア。今すぐ印刷するだけでも作業できますか? 'print'メソッドで制御する必要があります。私が持っている1つの質問は、「p.before + p.match + p.after」を使用すべきかどうかです。 – ilya1725

+0

元のスクリプトと同じようにデータが非同期に返されるため、すぐに印刷することはできません。 p.beforeは、一致する文字列の前のすべてを返します。一致した文字列がプロンプトであるため、すべてのコマンド出力はその前に来ています。 – Edu