python pexpect module: How to save output into a variable

166 Views Asked by At

When using the python3 pexpect module, how do you save everything that was printed to stdout into a list or variable that I can look at afterwards?

Here's a really basic example where we are just waiting for "Prompt" and then sending "foo". Afterwards I want to check what was in STDOUT and print data based on that. It seems that once you run p.read() it empties and is no longer accessible? How can I save the entire stdout output and access it later on, even after p.close() is run? In this example if the if statement is true it works but if it is false you can no longer read what was in stdout with p.read().

import pexpect

p = pexpect.spawn(cmd)
p.expect("Prompt")
p.sendline("foo")


if "Command was successful" in p.read():
  print ("successful")
else:
  print (p.read())

p.expect(pexpect.EOF)
p.close()
1

There are 1 best solutions below

2
Firdaus On

This is simple example, without logging and parallel execution like "threads\multiprocessing\concurent" A simplest way to save prints from your host\switch or smth, it's using .before.decode('utf-8')

Here is example of function that receive hostIP\name, log, pw, and list of commands:

def connectToHost(Ip, login, password, cmdPool):
    output=''
    Port = "22"
    HostKeyCheck = " -o StrictHostKeyChecking=no "
    ssh = pexpect.spawn("ssh -p "+Port+HostKeyCheck+login+"@"+ Ip, timeout=30)
    ssh.expect(r'sword:')
    ssh.sendline(password)
    print('Connected to '+ Ip)
    ssh.expect('$')
    output+=ssh.before.decode('utf-8')
    for cmdLine in cmdPool:
        ssh.sendline(cmdLine)
        ssh.expect('$')
        output+=ssh.before.decode('utf-8')
    ssh.close()
    return output

usage:

login = 'user'
password = '192929'
cmdPool = [
'ls -al',
'pwd',
'du -hs',
]
hosts = ['1.1.1.1', '12.2.2.2']
results = []
for ip in hosts:
    results.append(connectToHost(ip, login, password, cmdPool))
print(results)

Next step you can add something like logging instead of print(). Then you can use parallel if u need.

P.s Pay attention if u need log it into file pexpect has native arg logfile. This is example from pexpect docs:

child = pexpect.spawn('some_command')
fout = open('mylog.txt','wb')
child.logfile = fout