简体   繁体   中英

Python pexpect not working as expected

Im trying to write a program that runs some shell commands wit emulated user data.

The problem is that the shell command does not run correctly without this line in the end of the code:

raw_input('press <enter> to exit')

How can i get rid of that line?

child = pexpect.spawn('grunt init:gruntfile')
child.logfile_read = sys.stdout

child.expect ('Is the DOM involved in ANY way?')
child.sendline ('y')
child.logfile_read = sys.stdout

child.expect ('Will files be concatenated or minified?')
child.sendline ('y')
child.logfile_read = sys.stdout

child.expect ('Will you have a package.json file?')
child.sendline ('y')
child.logfile_read = sys.stdout

child.expect ('Do you need to make any changes to the above before continuing?')
child.sendline ('n')
child.logfile_read = sys.stdout

raw_input('press <enter> to exit')

The problem appears to be that without the raw_input to slow the program down, your python script is exiting before the child process is finished (and killing the child process in the process).

I think pexpect.wait() is supposed to handle this situation, but it sounds from the documentation like wait() will hang if there is unread output after the child process exits, and without knowing the details of your child process I can't say whether or not there is a risk that will happen. Some combination of read() and wait() might work, or if it's too much trouble to figure that out you could just time.sleep() a number of seconds.

I know that it has been a while since this question was asked, but I came across it and thought I would volunteer what worked for me.

I basically just setup a while loop that asked if the process was complete and then would throw an error if it never completed. That way I would have a more flexible wait that would error out in a way that was more meaningful to me while not gumming up my automation too bad.

I should also point out that this was for waiting for something to execute at the end of a series of interactive prompts before the program exited. So, if you are waiting for something that is in the middle of a process, then this wouldn't work so well. However, you probably could modify it to handle different situations.

import time, sys, pexpect


some_function():
    child = pexpect.spawn('some command here')

    if debugging:  # Just in case you also want to see the output for debugging
        child.logfile = sys.stdout

    # Do stuff
    child expect('some regex')
    child sendline('some response')

    sleep_count = 0  # For tracking how long it slept for.
    acceptable_duration = 120  # The amount of time that I'm willing to wait

    # Note that apparently solaris can take a while to reply to isalive(),
    # so the process may go a lot longer than what you set the duration to.

    while child.isalive():
        if sleep_count > acceptable_duration
            sys.stderr.write("Useful text explaining that the process never exited."
            sys.exit(1)
        time.sleep(1)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM