Changing the system clock with pexpect confuses pexpect!

Saqib Ali saqib.ali.75 at gmail.com
Mon Dec 26 03:03:57 EST 2011


See my code below.

I'm controlling a shell logged in as root with pexpect.

The class below has a method (startProc) which spawns a shell and
keeps it alive until told to destroy it (stopProc).

The other 2 methods in this class allow me to change the system clock
and to get the IP Address of this machine.

They all work fine.... except when I advance the system clock, and
then try to get the IP Address.
In that case, I get an exception because pexpect incorrectly thinks
the output it is getting from ifconfig is invalid. But it is not.
Pexpect is just confused. This doesn't happen when I move the clock
backwards. It only happens when I move the clock forward.

I believe what is going on is that internally pexpect uses the system
clock to keep track of when it receives data from spawned processes.
When I mess with the clock, that messes up the internal workings of
pexpect.

Any suggestions what I should do? I have numerous concurrent pexpect
processes running when I modify the clock. Is there anyway to prevent
them all from getting totally screwed up??

-----------------------------------------------------------------------------------------------------


#!/usr/bin/env python
import pexpect, os, time, datetime, re

def reportPrint(string):
    print string

def reportAssert(condition, string)
    if condition == False:
        print string
        raise Exception


class rootManager:

    rootProc = None
    rootPrompt = "] % "
    myPrompt = "] % "

    def __init__(self):
        pass




    def startProc(self):
        if self.rootProc != None:
            reportPrint("\t\t- Root Process is already created")
        else:
            self.rootProc = pexpect.spawn ('/bin/tcsh',)
            i = self.rootProc.expect([pexpect.TIMEOUT,
self.myPrompt,])
            reportAssert(i != 0, "Time-Out.... exiting")

            reportPrint("\t\t- Sending su")
            self.rootProc.sendline("su")
            i = self.rootProc.expect([pexpect.TIMEOUT, "Password: ",])
            reportAssert(i != 0, "Time-Out.... exiting")

            reportPrint("\t\t- Sending Password")
            self.rootProc.sendline(ROOT_PASSWORD)
            i = self.rootProc.expect([pexpect.TIMEOUT,
self.rootPrompt,])
            reportAssert(i != 0, "Time-Out.... exiting")

            reportPrint("\t\t- Root Process created")


    def getIPAddr(self):
        reportAssert(self.rootProc != None, "No active Root Process!")

        reportPrint("\t\t- Sending ifconfig -a")
        self.rootProc.sendline("ifconfig -a")
        i = self.rootProc.expect([pexpect.TIMEOUT, self.rootPrompt,])
        reportAssert(i != 0, "Time-Out.... exiting")

        outputTxt = self.rootProc.before
        ipList = [i for i in re.compile("(?<=inet )\d{1,3}\.\d{1,3}\.
\d{1,3}\.\d{1,3}").findall(outputTxt) if i != "127.0.0.1"]
        reportAssert(len(ipList) == 1, "Cannot determine IP Address
from 'ifconfig -a': \n%s" % outputTxt)
        return ipList[0]


    def changeClock(self, secondsDelta):
        reportAssert(self.rootProc != None, "No active Root Process!")

        newTime = datetime.datetime.now() +
datetime.timedelta(seconds=secondsDelta)
        dateStr = "%02d%02d%02d%02d%s" % (newTime.month, newTime.day,
newTime.hour, newTime.minute, str(newTime.year)[-2:])
        reportPrint("\t\t- Sending 'date %s' command" % dateStr)
        self.rootProc.sendline("date %s" % dateStr)
        #Remember, by changing the clock, you are confusing pexpect's
timeout measurement!
        # so ignore timeouts in this case
        i = self.rootProc.expect([pexpect.TIMEOUT,
self.rootPrompt,],)






    def stopProc(self):
        if self.rootProc == None:
            reportPrint("\t\t- Root Process is already destroyed")
        else:

            reportPrint("\t\t- Sending exit command")
            rootProc.sendline("exit")
            i = rootProc.expect([pexpect.TIMEOUT, self.myPrompt])
            reportAssert(i != 0, "Time-Out.... exiting")

            reportPrint("\t\t- Sending exit command")
            rootProc.sendline("exit")
            i = rootProc.expect([pexpect.TIMEOUT, pexpect.EOF])
            reportAssert(i != 0, "Time-Out.... exiting")
            self.rootProc.close()
            self.rootProc = None
            reportPrint("\t\t- Root Process Destroyed")






More information about the Python-list mailing list