Python expect что это

pexpect : Python’s expect module to Control Interactive Programs

We are familiar with Expect, a Tcl package written by Don Libes. Using this Tcl package we can control arbitrary interactive programs and processes. One of the classic examples shows how to to expect to automate a login sequence.

Did you know Python has an “Expect” like module too? It is called pexpect, and the author wrote it based on the Tcl Expect, but he wanted an easier interface. His solution was to develop a Python module with most of the capabilities of Expect.

Example

This example consists of two parts:

1) A parent Python script, and 2) An interactive ‘c’ program called ioTest.

The ‘c’ program reads stdin, then lowercases the characters it receives and write the resulting string to stdout.

First, we show the execution of ioTest by itself:

$ ./ioTest ZZZ Child lowercases sends zzz YYY Child lowercases sends yyy XXX Child lowercases sends xxx

Now we show remote control of ioTest from Python:

$ ./pexpectTest.py Write to subprocess: 'AA' Received from child: aa Write to subprocess: 'BB' Received from child: bb Write to subprocess: 'CC' Received from child: cc Write to subprocess: 'DD' Received from child: dd

Source Code

import pexpect if __name__ == '__main__': shell_cmd = "/home/anukul/ioTest" child = pexpect.spawn(shell_cmd) for cc in ['AA','BB','CC','DD']: msg = "%s" % cc print "\nWrite to subprocess: '%s'" % msg.strip() child.sendline(msg) n = child.expect(["[a-z]+\r\n"]) print "Received from child: ", child.match.group(0)

Another example

We have one “command line utility : cmlsh” to configure network interface

Читайте также:  Modern java learn java 8 features by coding it

Fisrt, we will execute shell manually

root@verma:[ji]$ cmlsh ZebOS-XP version 2.1.0 IPIRouter 01/09/17 00:23:55 verma>en verma# verma#configure terminal Enter configuration commands, one per line. End with CNTL/Z. verma(config)# verma(config)#interface eth2 verma(config-if)# verma(config-if)#mtu 1300 verma(config-if)#end verma# verma#show running-config interface eth2 ! interface eth2 mtu 1300 ! verma# verma#exit root@verma:[ji]$

Now we will write one python script to do the same

root@verma:[ji]$ cat run_cmlsh.py #! /usr/local/bin/python import pexpect if __name__ == '__main__': shell_cmd = "cmlsh" child = pexpect.spawn(shell_cmd) child.expect(".*>") child.sendline("enable") # Iterate over the commands for cmd in ['conf t','interface eth2','mtu 1380','end','show running-config interface eth2','exit']: msg = ("%s\r") %cmd child.sendline(msg) child.expect(".*#") print child.after  child.interact()

When we run this script we can do the same thing what we did manually

root@verma:[ji]$ python run_cmlsh.py enable verma#conf t Enter configuration commands, one per line. End with CNTL/Z. verma(config)# verma(config)#interface eth2 verma(config-if)# verma(config-if)#mtu 1380 verma(config-if)# verma(config-if)#end verma# verma#show running-config interface eth2 ! interface eth2 mtu 1380 ! verma# verma#

Match multiple responses

The pattern given to expect() may be a regular expression or it may also be a list of regular expressions. This allows you to match multiple optional responses. The expect() method returns the index of the pattern that was matched. For example, say you wanted to login to a server. After entering a password you could get various responses from the server – your password could be rejected; or you could be allowed in and asked for your terminal type; or you could be let right in and given a command prompt. The following code fragment gives an example of this:

child.expect('password:') child.sendline(my_secret_password) # We expect any of these three patterns. i = child.expect (['Permission denied', 'Terminal type', '[#\$] ']) if i==0: print('Permission denied on host. Can\'t login') child.kill(0) elif i==1: print('Login OK. need to send terminal type.') child.sendline('vt100') child.expect('[#\$] ') elif i==2: print('Login OK.') print('Shell command prompt', child.after) 

If nothing matches an expected pattern then expect() will eventually raise a TIMEOUT exception. The default time is 30 seconds, but you can change this by passing a timeout argument to expect():

# Wait no more than 2 minutes (120 seconds) for password prompt. child.expect('password:', timeout=120)

Example log input and output to a file:

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

Example log to stdout:

# In Python 2: child = pexpect.spawn('some_command') child.logfile = sys.stdout # In Python 3, spawnu should be used to give str to stdout: child = pexpect.spawnu('some_command') child.logfile = sys.stdout 

The logfile_read and logfile_send members can be used to separately log the input from the child and output sent to the child. Sometimes you don’t want to see everything you write to the child. You only want to log what the child sends back. For example:

child = pexpect.spawn('some_command') child.logfile_read = sys.stdout 

You will need to pass an encoding to spawn in the above code if you are using Python 3.

To separately log output sent to the child use logfile_send:

Special EOF and TIMEOUT patterns

If the child has died and you have read all the child’s output then ordinarily expect() will raise an EOF exception. You can read everything up to the EOF without generating an exception by using the EOF pattern expect. In this case everything the child has output will be available in the before property.

If nothing matches an expected pattern then expect() will eventually raise a TIMEOUT exception. The default time is 30 seconds, but you can change this by passing a timeout argument to expect():

index = handler.expect([expect_str, pexpect.EOF, pexpect.TIMEOUT],int(TIMEOUT_SEC)) if index == 0: # Do your stuffs elif index == 1: print "EOF exception.\n" handler.kill(0) sys.exit(1) else: print "TIMEOUT exception.\n" handler.kill(0) sys.exit(1)

Источник

Expects¶

Expects is an expressive and extensible TDD/BDD assertion library for Python. Expects can be extended by defining new matchers.

Usage¶

Just import the expect callable and the built-in matchers and start writing test assertions.

from expects import * expect([]).to(be_empty) expect(False).not_to(be_true) expect( 'name': 'Jack', 'email': 'jack@example.com' >).to(have_key('name', match('\w+'))) expect(str).to(have_property('split') & be_callable) expect(lambda: foo).to(raise_error(NameError)) expect('Foo').to(equal('Bar') | equal('Foo')) 

Contents¶

  • Installation
    • PyPI
    • GitHub
    • equal
    • be
    • be_true
    • be_false
    • be_none
    • be_a / be_an
    • be_empty
    • be_above
    • be_below
    • be_above_or_equal
    • be_below_or_equal
    • be_within
    • be_callable
    • have_len / have_length
    • have_property
    • have_properties
    • have_key
    • have_keys
    • contain
    • contain_exactly
    • contain_only
    • start_with
    • end_with
    • match
    • raise_error
    • Reference
    • Introduction
    • Tutorial
    • Advanced
    • Testing
    • 0.9.0 (2018-10-25)
    • 0.8.0 (2016-05-15)
    • 0.8.0rc5 (2016-05-07)
    • 0.8.0rc4 (2015-10-14)
    • 0.8.0rc3 (2015-10-07)
    • 0.8.0rc2 (2015-08-14)
    • 0.8.0rc1 (2015-07-17)
    • 0.7.0 (2015-06-26)
    • 0.7.1 (2015-06-09)
    • 0.7.0 (2015-03-01)
    • 0.6.2 (2014-12-10)
    • 0.6.1 (2014-11-30)
    • 0.6.0 (2014-11-24)
    • 0.5.0 (2014-09-20)
    • 0.4.2 (2014-08-16)
    • 0.4.1 (2014-08-16)
    • 0.4.0 (2014-08-15)
    • 0.3.0 (2014-06-29)
    • 0.2.3 (2014-06-04)
    • 0.2.2 (2014-05-20)
    • 0.2.1 (2014-03-22)
    • 0.2.0 (2014-02-05)
    • 0.1.1 (2013-08-20)
    • 0.1.0 (2013-08-11)

    Indices and tables¶

    © Copyright 2014, Jaime Gil de Sagredo Revision 386705c4 .

    Versions latest stable v0.9.0 v0.8.0 v0.8.0rc1 v0.7.2 v0.7.1 v0.7.0 master Downloads pdf htmlzip epub On Read the Docs Project Home Builds Free document hosting provided by Read the Docs.

    Источник

Оцените статью