1

I'm automating a installer using pexpect, which works nicely. However, I would like to replace the pexpect.interact() with some sort of stdout, which would allow me to keep track of the progress bar of the installer:

Please wait while Setup installs on your computer.

 Installing
 0% ______________ 50% ______________ 100%
 #########################################

----------------------------------------------------------------------------
Setup has finished installing on your computer.

View readme file [Y/n]: n

[Errno 5] Input/output error

The source code looks like:

## A bunch of informations being given to the installer above
## Do you want install? y
child.sendline('y')
## now I keep tracking of the installation bar progress ... 
child.interact()
## View readme file [Y/n]: n
child.sendline('n')

so the last part is being done manually, become I can't get of the child.interact() once the install has been completed. How could I accomplish that?

cybertextron
  • 10,547
  • 28
  • 104
  • 208

1 Answers1

1

I had to do the same thing once. The problem is that things are working in line buffered mode by default. Here is how I worked around it:

Right after you create your child (I am assuming this is a pexpect.spawn) you can set the attribute child.logfile to something - this doesn't have to be a logfile literally, it can be any file handle. In your case, you can set it to sys.stdout but open this file handle in unbuffered mode.

Working example:

#!/usr/bin/env python

import pexpect
import sys
import time
import os

def potato():
    for i in range(20):
        time.sleep(0.1)
        sys.stdout.write(str(i))
        sys.stdout.flush()
    sys.stdout.write('bye\n')



if __name__ == '__main__':
    if sys.argv[-1] == 'potato':
        potato()
    else:
        child = pexpect.spawn(__file__ + ' potato')
        child.logfile = os.fdopen(sys.stdout.fileno(), 'w', 0)
        child.expect('bye')
wim
  • 338,267
  • 99
  • 616
  • 750
  • Could you please add more details? – cybertextron Jan 20 '14 at 17:18
  • I quite didn't understand everything you said ... I was a little confused how could I do it – cybertextron Jan 20 '14 at 17:25
  • Not quite, because I have to wait until the installer is finished ... otherwise the last input will enter, and there's an error ... but the stdout part is correct – cybertextron Jan 20 '14 at 17:36
  • `Exception pexpect.ExceptionPexpect: ExceptionPexpect() in > ignored` – cybertextron Jan 20 '14 at 17:39
  • Try changing the line `child.logfile = os.fdopen(sys.stdout.fileno(), 'w', 0)` to simply `child.logfile = sys.stdout`. Do you see the result you want? Some things changed in python since the last time I was working with this – wim Jan 20 '14 at 17:51
  • No, it didn't change much ... the problem is I have to wait for the installer to complete, which is what `child.interact()` does ... – cybertextron Jan 20 '14 at 20:51
  • 1
    Well there are other ways of doing that. I can't say exactly how without seeing the output of your installer, but you should try using something like `child.expect('readme')` if you are waiting for the prompt to "View readme file" – wim Jan 20 '14 at 22:15
  • Please post an [SSCCE](http://sscce.org/). Are you able to run the example shown in my question correctly? This is a working method for me, so if you are having some problem with it then you'll need to show how to reproduce the problem. – wim Feb 04 '14 at 09:38