I need to script/automate an interactive terminal client using Python. The client accepts three arguments and runs as follows:
>./myclient <arg1> <arg2> <arg3>
Welcome...
blah...
blah..
[user input]
some more blah... blah... for the input entered
blah..
blah..
[basically it accepts input and puts the output in the console until the user types 'quit']
Now I need to automate this in Python and the console output saved in a file.
-
i tried the Popen but couldn't manage to run the terminal client effectively. I also wasn't able to send more than one input using communicate(). When i used stdin=PIPE and then send the data using stdin.read the client was acting weirdconfused1– confused12012年05月05日 15:22:41 +00:00Commented May 5, 2012 at 15:22
2 Answers 2
You probably want to use pexpect (which is a pure-python version of the venerable expect).
import pexpect
proc = pexpect.spawn('./myclient <arg1> <arg2> <arg3>')
proc.logfile = the_logfile_you_want_to_use
proc.expect(['the string that tells you that myclient is waiting for input'])
proc.sendline('line you want to send to myclient')
proc.expect(['another line you want to wait for'])
proc.sendline('quit') # for myclient to quit
proc.expect([pexpect.EOF])
Something like this should be enough to solve your case. pexpect is capable of a lot more though, so read up on the documentation for more advanced use-cases.
2 Comments
proc.sendline('input1') time.sleep(60) proc.sendline('input2') but the issue is that it doesn't wait. It seems to send the input irrespective of the thread.sleep(60)..You could have a look at http://docs.python.org/library/cmd.html.
Example code:
import cmd
import sys
class Prompt(cmd.Cmd):
def __init__(self, stufflist=[]):
cmd.Cmd.__init__(self)
self.prompt = '>>> '
self.stufflist = stufflist
print "Hello, I am your new commandline prompt! 'help' yourself!"
def do_quit(self, arg):
sys.exit(0)
def do_print_stuff(self, arg):
for s in self.stufflist:
print s
p = Prompt(sys.argv[1:])
p.cmdloop()
Example test:
$ python cmdtest.py foo bar
Hello, I am your new commandline prompt! 'help' yourself!
>>> help
Undocumented commands:
======================
help print_stuff quit
>>> print_stuff
foo
bar
>>> quit
In order to save the output to a file, you can write what usually goes to stdout also to a file, using for example this class:
class Tee(object):
def __init__(self, out1, out2):
self.out1 = out1
self.out2 = out2
def write(self, s):
self.out1.write(s)
self.out2.write(s)
def flush(self):
self.out1.flush()
self.out2.flush()
You can use it like this:
with open('cmdtest.out', 'w') as f:
# write stdout to file and stdout
t = Tee(f, sys.stdout)
sys.stdout = t
A problem is that the commands read in via stdin do not appear in this output, but I believe that this can be easily solved.