【问题标题】:Print and pexpect logging打印和预期日志记录
【发布时间】:2012-11-15 10:45:56
【问题描述】:

我有一段代码使用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 manual page:“但是请注意,缓冲会影响此行为,因为 输入以不可预测的块的形式到达”。因此它可能会影响日志记录。

【问题讨论】:

    标签: python pexpect


    【解决方案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                                                        
    

    【讨论】:

    • 好主意。立即打印也可以吗?然后它应该由print 方法控制。我的一个问题是:应该使用p.before + p.match + p.after 吗?
    • 无法立即打印,因为数据是异步返回的,就像在原始脚本中一样。 p.before 返回匹配字符串之前的所有内容。由于匹配的字符串是提示符,所以所有的命令输出都已经在它之前了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-10
    • 1970-01-01
    • 1970-01-01
    • 2014-06-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多