Jan. 28, 2013

How to use the Pexpect Module

This article is based on documentation from http://www.noah.org/wiki/pexpect and http://pypi.python.org/pypi/pexpect/ The reason I started to use Pexepect was because I was looking for a module that can take care of some of the automation needs I have (mostly with ssh and ftp). You can use other modules such as subprocess, but I find this module easier to use. Note, this post is not for a Python beginner, but hey it's always fun to learn new things

What is Pexpect?

Pexpect is a pure Python module that makes Python a better tool for controlling
and automating other programs.

Pexpect is basically a pattern matching system. It runs program and watches

When output matches a given pattern Pexpect can respond as if a human were
typing responses. 

What can Pexpect be used for?

Pexpect can be used for automation, testing, and screen scraping.

Pexpect can be used for automating interactive console applications such as
ssh, ftp, passwd, telnet, etc.
It can also be used to control web applications via `lynx`, `w3m`, or some
other text-based web browser.

Installing Pexpect

The latest version of Pexpect can be found here
wget http://pexpect.sourceforge.net/pexpect-2.3.tar.gz
tar xzf pexpect-2.3.tar.gz
cd pexpect-2.3
sudo python ./setup.py install
# If your systems support yum or apt-get, you might be able to use the
# commands below to install the pexpect package. 

sudo yum install pexpect.noarch

# or

sudo apt-get install python-pexpect

Pexpect Methods

There are two important methods in Pexpect: expect() and send() (or sendline()
which is like send() with a linefeed). 

The expect() method

Waits for the child application to return a given strong. 

The string you specify is a regular expression, so you can match complicated
emember that any time you try to match a pattern that needs look-ahead that 
you will always get a minimal match.

The following will always return just one character:
child.expect ('.+')

Specify correctly the text you expect back, you can add '.*' to the beginning
or to the end of the text you're expecting to make sure you're catching
unexpected characters
This example will match successfully, but will always return no characters:
child.expect ('.*')
Generally any star * expression will match as little as possible.

The pattern given to expect() may also be a list of regular expressions,
this allows you to match multiple optional responses. 
(example if you get various responses from the server)

The send() method

Writes a string to the child application. 

From the child's point of view it looks just like someone typed the text from
a terminal. 

The before and after properties

After each call to expect() the before and after properties will be set to the
text printed by child application. 

The before property will contain all text up to the expected string pattern. 

You can use child.before to print the output from the other side of the connection

The after string will contain the text that was matched by the expected pattern. 

The match property is set to the re MatchObject. 

Connect and download a file from a remote FTP Server

This connects to the openbsd ftp site and downloads the recursive directory

You can use this technique with any application.

This is especially handy if you are writing automated test tools.

Again, this example is copied from here
import pexpect
child = pexpect.spawn ('ftp ftp.openbsd.org')
child.expect ('Name .*: ')
child.sendline ('anonymous')
child.expect ('Password:')
child.sendline ('noah@example.com')
child.expect ('ftp> ')
child.sendline ('cd pub')
child.expect('ftp> ')
child.sendline ('get ls-lR.gz')
child.expect('ftp> ')
child.sendline ('bye')
In the second example, we can see how to get back the control from Pexpect

Connect to a remote FTP Server and get control

This example uses ftp to login to the OpenBSD site (just as above),
list files in a directory and then pass interactive control of the ftp session
to the human user.
import pexpect
child = pexpect.spawn ('ftp ftp.openbsd.org')
child.expect ('Name .*: ')
child.sendline ('anonymous')
child.expect ('Password:')
child.sendline ('noah@example.com')
child.expect ('ftp> ')
child.sendline ('ls /pub/OpenBSD/')
child.expect ('ftp> ')
print child.before    # Print the result of the ls command.
child.interact()       # Give control of the child to the user.

EOF, Timeout and End Of Line

There are special patters to match the End Of File or a Timeout condition.

I will not write about it in this article, but refer to the official documentation
because it is good to know how it works. 

Share this article

Recommended Python Training – DataCamp

For Python training, our top recommendation is DataCamp.

Datacamp provides online interactive courses that combine interactive coding challenges with videos from top instructors in the field.

Datacamp has beginner to advanced Python training that programmers of all levels benefit from.


Download Our Free Guide To Learning Python

* indicates required

Read more about:
Disclosure of Material Connection: Some of the links in the post above are “affiliate links.” This means if you click on the link and purchase the item, I will receive an affiliate commission. Regardless, PythonForBeginners.com only recommend products or services that we try personally and believe will add value to our readers.