Sie sind auf Seite 1von 15

Tcl/Expect

EXPECT
What’s Expect ?

 Expect is a tool for automating interactive applications such as telnet, ftp, passwd, fsck, rlogin, tip, etc.

Expect provides,

 Start and control an external application


 Simulate user interaction with the application by transmitting keystrokes and capturing output
 This extension provides the key component for remotely controlling the equipment involved in a network test by spawning and
controlling external telnet connections to the equipment

History behind : http://expect.nist.gov/index.html

Advantages (tcl),

 Open source
 Tcl/Tk --- helps to develope GUI programming
 Tcl/expect --- helps to interact with devices/external applications

Disadvantages (tcl),

 Tcl scripts are interpreted instead of compiled, execution of the scripts will obviously be slower than an equivalent
C or C++ implementation.
 Tcl/Tk is the lack of a rich set of data structures
Starting an Application
To start the external application,

Syn :
spawn [-<opts>] <program>

Ex. :
expect1.1> spawn /bin/sh
spawn /bin/sh
302
expect1.2>

Here,
- Expect 'spawn' command to run a shell in a separate process

- In order to control the external application, the application's standard input, output, and error file descriptors are
redirected to the Tcl interpreter (Expect)

-Expect can now simulate user interaction with the the application under control by sending it keystrokes and reading the
resulting output

- Using spawn ids, Expect can control multiple applications from a single Tcl interpreter.

- Each Expect command supports a '-i' option which allows you to specify the target spawn id for the command.

NOTE : Additionally, the spawn id returned by the 'spawn' command is stored in a global variable named spawn_id. If no spawn id is
specified on an Expect command, the command will use the id contained in the 'spawn_id' variable.
Interacting with an Application

Sending Keystrokes to an Application

Syn :

send [-<flags>] <string>


Ex :

send “ls \r”

Here,
- Keystrokes can be sent using a single/multiple send commands.

- They must include all the keystrokes required to get the application to read the input (e.g include a return ‘\r’ at the end
of the command)

- In this example, we are sending Unix “ls” command to the shell process that we previously spawned.

- We terminated the command with a return ('\r') to simulate the pressing of the Return key. The shell won't process the
input until Return is entered.

- We used double quotes around the transmitted string to insure that the Tcl interpreter expands '\r' to the proper control
character. If we had quoted the test in curly braces (e.g. {ls\r}) the interpreter would have send the literal characters '\r' to the
shell.

- The 'send' command accepts an optional '-i <spawn id>' option that can be used specify the target application for sending.
We've excluded his option since Expect will use the contents of the 'spawn_id' variable initialized with the shell spawn id by the
'spawn' command.

- The 'send' command return nothing


Manipulating outputs from an application - 1

Expecting output from an Application

Output from an application under Expect control is not visible to the script until the expect command is used to parse the output from the
application.
Syn :
expect { [-<opts>] body] ... }

- 'expect' command is similar to that of the Tcl 'case' statement

- The command allows you to associate actions to be executed, expressed as Tcl statements, when a specific character
patterns are recognized in the output from the application.

The character patterns can be specified using glob or regular expression syntax

Example :

expect {
-re {\$ $} {}
timeout {error “Unable to capture ls output” }
}
Manipulating outputs from an application - 2
Getting Application Output

 Expect accumulates the characters in the response in an internal buffer which is in accessible by the script.

 Expect is constantly accumulating application output to insure that nothing is lost before the script calls for the output.

 A script "calls" for output from an application by issuing the 'expect' command. When a pattern in an 'expect' statement matches the
contents of the internal Expect buffer , the matching characters are moved to a global array:

expect_out(buffer) Contains all previously matched characters


expect_out(0,string) Contains the characters that matched the pattern
expect_out(<n>,string) Contains the characters matching subpattern <n>

NOTE : There are no spaces within the array index -- you will get an error if you try to reference expect_out(0, string).
Manipulating outputs from an application - 3
Example : 1
Application returns : "abcdefgh\n“

expect "b(.*)e([a-z])g":
expect1.7> echo $expect_out(buffer)
abcdefg
expect1.8>

echo $expect_out(0,string)
bcdefg
expect1.9>

echo $expect_out(1,string)
cd

expect1.10> echo $expect_out(2,string)


f

Example 2 :

expect "cd":
expect1.5> echo $expect_out(buffer)
abcd
expect1.6> echo $expect_out(0,string)
cd
Manipulating outputs from an application - 4

 NOTE : Expect accumulates all application output in an internal buffer as it is received. This buffer is what's matched against by the

'expect' command to transfer output characters to script accessible variables. The Expect match_max command can be used to specify

the size of the internal buffer used by Expect to accumulate application output. If the application you're controlling generates a great

deal of output between prompts, you may need to increase the size of the buffer from 2048 as in the following example:

expect1.5> match_max -i $spawn_id 8196

 exp_continue within each action body instructs Expect to remain within the 'expect' body and continue to scan application output.
Example 1 : Open separate sh and get the files
#! /export/home/pdharmam/ats4.1/bin/expect #! /export/home/pdharmam/ats4.1/bin/expect

spawn /bin/sh spawn /bin/sh


set flag 1
expect "\$ $"
send "ls\r" expect {
expect "(.*)\r\n\$ $"
puts $expect_out(buffer) -re {\$ $} {
if {$flag == 1} {
set flag 0
send "ls\r"
close -i $spawn_id exp_continue
}
}

-re "(.*)\r\n\$ $" { puts $expect_out(buffer) }

timeout { error "\nTime out..." }

close -i $spawn_id
Example 2 : List the file/directories from the home directory
#! /export/home/pdharmam/ats4.1/bin/expect arf-mpls12:/users/pdharmam/tcl/dir1> ./a.tcl
set system “xxxx"
set username “xxx" Buffer Full..
set passwd “xxxx”
ls
log_user 0 a.tcl.bak back-tcl Mail typescript
a.txt corn post XML
set command "ls"
ats4.1 cron Resmap
#/* To connect the device */ ats5.1.0 cs suite
spawn telnet $system ats5.1.0.tar.gz logsa-2 tcl
pdharmam@arf-mpls12%
expect {
-re {login: $} {
send "$username\r"
0th Index
exp_continue
} ls
-re {Password: $} { a.tcl.bak back-tcl Mail typescript
send "$passwd\r" a.txt corn post XML
exp_continue
}
ats4.1 cron Resmap
-re {Last(.*)\% $} { ats5.1.0 cs suite
send "$command\r" ats5.1.0.tar.gz logsa-2 tcl
exp_continue pdharmam@arf-mpls12%
}
-re "$command\r\n(.*)\r\npdharmam(.*)% $" {
1st Index
puts "\n Buffer Full..\n"
puts $expect_out(buffer)
puts "\n 0th Index \n" a.tcl.bak back-tcl Mail typescript
puts $expect_out(0,string) a.txt corn post XML
puts "\n 1st Index \n" ats4.1 cron Resmap
puts $expect_out(1,string)
ats5.1.0 cs suite
puts "\n 2nd Index \n"
puts $expect_out(2,string)
ats5.1.0.tar.gz logsa-2 tcl
}
2nd Index
timeout {
error "Unable to proceeds ...\n"
@arf-mpls12
}
}
arf-mpls12:/users/pdharmam/tcl/dir1>
Example 3 : Get ‘Show ver’ output
#! /export/home/pdharmam/ats4.1/bin/expect arf-mpls12:/users/pdharmam/tcl/dir1> ./b.tcl
global expect_out
Buffer ...
set system "1.1.1.1"
set name “xxxx" show ver
set passwd "lab" Cisco Internetwork Operating System Software
IOS (tm) C2600 Software (C2600-IPBASE-M), Version 12.3(6f), RELEASE
set command "show ver"
SOFTWARE (fc1)
log_user 0 Copyright (c) 1986-2005 by cisco Systems, Inc.
Compiled Tue 16-Aug-05 17:54 by ssearch
spawn telnet $system Image text-base: 0x80008098, data-base: 0x80ED16A0
set flag 1
ROM: System Bootstrap, Version 12.2(7r) [cmong 7r], RELEASE
expect { SOFTWARE (fc1)
-re {Password: $} {
send "$passwd\r" arf-tsmpls76a uptime is 3 weeks, 11 hours, 28 minutes
exp_continue System returned to ROM by power-on
}
System image file is "flash:c2600-ipbase-mz.123-6f.bin"
-re "\>$" {
cisco 2611XM (MPC860P) processor (revision 0x401) with
if {$flag != 0} { 126976K/4096K bytes of memory.
set flag 0 Processor board ID FTX0944A11V (2267036481)
send "$command\r"
M860 processor: part number 5, mask 2
exp_continue
} Bridging software.
} X.25 software, Version 3.0.0.
2 FastEthernet/IEEE 802.3 interface(s)
timeout { 32 terminal line(s)
error "Unable to ...."
32K bytes of non-volatile configuration memory.
}
}
49152K bytes of processor board System flash (Read/Write)

Configuration register is 0x2102


puts "\n Buffer ...\n"
puts $expect_out(buffer)
arf-tsmpls76a>
send "logout\r"
arf-mpls12:/users/pdharmam/tcl/dir1>
close -i $spawn_id
Example 4 : Get ‘Show ip int bri’ output with expect_out array index
#! /export/home/pdharmam/ats4.1/bin/expect arf-mpls12:/users/pdharmam/tcl/dir1> ./c.tcl
global expect_out spawn telnet 172.19.186.214
Trying 172.19.186.214...
set system “xxxx" Connected to 172.19.186.214.
set name “xxxxx" Escape character is '^]'.
set passwd "lab"

set command "show ip int bri “ User Access Verification


log_user 1
Password:
spawn telnet $system
arf-tsmpls76a>en
Password:
expect {
arf-tsmpls76a#show ip int bri
-re {Password: $} {
Interface IP-Address OK? Method Status Protocol
send "$passwd\r"
FastEthernet0/0 172.19.186.214 YES NVRAM up up
exp_continue
FastEthernet0/1 unassigned YES NVRAM administratively down down
} arf-tsmpls76a#

-re "\>$" { Buffer ...


send "en\r"
exp_continue show ip int bri
} Interface IP-Address OK? Method Status Protocol
FastEthernet0/0 172.19.186.214 YES NVRAM up up
-re "(Interface(.*))(\r\n$name\#)$" { FastEthernet0/1 unassigned YES NVRAM administratively down down
puts "\n Buffer ...\n" arf-tsmpls76a#
puts $expect_out(buffer)
puts "\n 0th Index ....\n" 0th Index ....
puts $expect_out(0,string)
puts "\n 1st Index ....\n" Interface IP-Address OK? Method Status Protocol
puts $expect_out(1,string) FastEthernet0/0 172.19.186.214 YES NVRAM up up
} FastEthernet0/1 unassigned YES NVRAM administratively down down
-re "$name\#$" {
arf-tsmpls76a#
send "$command\r"
1st Index ....
exp_continue
}
Interface IP-Address OK? Method Status Protocol
FastEthernet0/0 172.19.186.214 YES NVRAM up up
FastEthernet0/1 unassigned YES NVRAM administratively down down
timeout { arf-mpls12:/users/pdharmam/tcl/dir1>
error "Unable to ...."
}
send "logout\r"
close -i $spawn_id
Expect Logging
Expect Logging :

All interaction between Expect and an application under control (keystrokes and application output) is logged to file for later review.

Syn :
log_file [[-a] <filename>]

Here,
Given a <filename> argument, Expect begins logging dialogs to the specified file.
Use the '-a' option to append to an existing log file
Given no arguments, this command disables logging

In addition to logging information to a file, debugging information can be logged to the screen

Syn :

log_user {0 | 1}
Example 5 : Get ‘Show ip int bri’ output with logging
#! /export/home/pdharmam/ats4.1/bin/expect
global expect_out arf-mpls12:/users/pdharmam/tcl/dir1> ls a.txt
a.txt
set system “xxxx" arf-mpls12:/users/pdharmam/tcl/dir1> more a.txt
set name “xxxxx" Trying 172.19.186.214...
set passwd "lab" Connected to 172.19.186.214.
Escape character is '^]'.
set command "show ip int bri “

log_user 1 User Access Verification

log_file a.txt Password:


#log_file –a a.txt arf-tsmpls76a>en
Password:
arf-tsmpls76a#show ip int bri
spawn telnet $system
Interface IP-Address OK? Method Status Protocol
expect {
FastEthernet0/0 172.19.186.214 YES NVRAM up up
-re {Password: $} {
FastEthernet0/1 unassigned YES NVRAM administratively down down
send "$passwd\r" arf-tsmpls76a#
exp_continue arf-mpls12:/users/pdharmam/tcl/dir1>
}
-re "\>$" {
send "en\r"
exp_continue
}

-re "(Interface(.*))(\r\n$name\#)$" {
puts "\n Buffer ...\n"
puts $expect_out(buffer)
puts "\n 0th Index ....\n"
puts $expect_out(0,string)
puts "\n 1st Index ....\n"
puts $expect_out(1,string)
}
-re "$name\#$" {
send "$command\r"
exp_continue
}
timeout {
error "Unable to ...."
}
send "logout\r"
close -i $spawn_id
Thanks

Das könnte Ihnen auch gefallen