MrDuk
MrDuk

Reputation: 18322

How can I parse pexpect in real time?

I'm considering pexpect (totally open to alternatives, if there are better ones I'm not aware of) in one of our deploy script wrappers -- but I need a way to read the output in real-time, not only once we've hit the EOF. Since this is a deployment package, used for all environments, we need to catch issues as soon as they happen (and potentially hit the emergency exit if it's really bad).

Is there such a thing I can use? Ideally, I'd like to make use of our already existing logger..

def SetupLogging():
    # the logger
    # set to DEBUG since the reports should already give
    # any information we're looking for at a glance
    global log 
    log = logging.getLogger('ansiwrap')
    log.setLevel(logging.DEBUG)

    # create file handler which logs everything
    fh = logging.FileHandler('ansiwrap.debug', mode='w')
    fh.setLevel(logging.DEBUG)

    # create console handler with a higher log level
    ch = logging.StreamHandler()
    ch.setLevel(logging.INFO)

    # create formatter and add it to the handlers
    formatter = logging.Formatter('[%(asctime)s] | %(name)s - %(levelname)s - %(message)s')
    ch.setFormatter(formatter)  
    fh.setFormatter(formatter)

    # add the handlers to logger
    log.addHandler(ch)
    log.addHandler(fh)

For completeness, here is an example implementation, but it seems clunky to me:

child = pexpect.spawn(cmd)
while True:
    try:
        child.expect('\n')
        print(child.before)
    except pexpect.EOF:
        break 

Upvotes: 0

Views: 1478

Answers (1)

Sharad
Sharad

Reputation: 2013

EOF is hit when the child process terminates. To get real time output of the commands being sent and replies received, you can log the output to stdout or a file.

Spawn class of Pexpect has a logfile_read attribute which writes the output of child process to the file specified. Modifying the code as shown below will do the job. I am using sys.stdout which will print everything to the console. You can open a file and use that as well

child = pexpect.spawn(cmd)
child.logfile_read = sys.stdout
while True:
    try:
        child.expect('\n')
        print(child.after)
    except pexpect.EOF:
        break 

The reason the while block is still needed is because as per documentation logfile is flushed after every write. Since writes are not there, a call to expect will cause the flushing to the file.

Upvotes: 1

Related Questions