TDN169
TDN169

Reputation: 1427

Use pexpect to detect end of bash output

I am using pexpect to run a bash instance:

bash = pexpect.spawn("/bin/bash")

I would like to be able to "expect" the end of this output. At the moment I'm using the following:

bash.sendline("ls -ltr")
lines = []
while True:
    try:
        bash.expect("\r\n", timeout=0.1)
        lines.append(bash.before)
    except pexpect.TIMEOUT:
        print "TO"
        break

This is effective, however it seems like it would be more efficient to be able to detect the end of the output without needing to wait for pexpect.TIMEOUT.

Upvotes: 1

Views: 2779

Answers (2)

nmz787
nmz787

Reputation: 2170

I found my this great snippet (set_unique_prompt) in the pxssh.py module of pexpect, here's a modified example:

UNIQUE_PROMPT = "\[PEXPECT\][\$\#] "
PROMPT_SET_CSH = "set prompt='[PEXPECT]\$ '"
def set_unique_prompt():
    # expect that the default shell prompt will display at least a "> "
    c.expect('>\s+$')
    c.sendline(PROMPT_SET_CSH)
    i = c.expect([pexpect.TIMEOUT, UNIQUE_PROMPT], timeout=2)
    if i == 0:
        print(c.before)
        print(c.after)
        raise Exception("couldn't set CSH shell prompt to something unique that we can match on!")

# start new process
c = pexpect.spawn('csh')
set_unique_prompt()
print("started new shell and renamed it's prompt")

c.sendline('start_long_running_command')
while True:
    i = c.expect([pexpect.TIMEOUT, self.UNIQUE_PROMPT], timeout=5)
    if i:
        break
    else:
        print('command still running')
print('long running command finished')

it basically starts a shell (in this case CSH), then it first changes the prompt signature to something we don't expect will be in the command-output (in this case we set it to "[PEXPECT]$ ", then we can EXPECT the unique-prompt, so we know when the shell is done.

For BASH, just change the PROMPT_SET_CSH variable to the command BASH uses to change it's prompt-string... pxssh.py recommends PROMPT_SET_SH = "PS1='[PEXPECT]\$ '"

Upvotes: 1

quemeraisc
quemeraisc

Reputation: 492

You should expect your prompt. Say your prompt is "s", your code should be :

bash.expect(">")

or even set a variable first for your prompt (in case later on you want to change your prompt;))

prompt = ">"
bash.expect(prompt)

Upvotes: 4

Related Questions