TCL:
• “Tcl” is the language used to develop automated test scripts.
• Developed by John Ousterhout at UC Berkeley.
• It is an interpreted language – provides fundamental operations of all languages such as flow control and variable management.
• Tcl provides a fundamental command set which is to be expanded by adding “extensions” to the language to perform specific operations (e.g. “Tk” – Tool Kit, the first Tcl Extension for GUI/widget development)
Start and Exit the Tcl Interactive Session
• Tcl is an interactive interpreter – you can start it from UNIX shell and type commands
• Setting the Environment
• Type tclsh or expect at Unix Shell prompt to start interactive interpreter
• Type exit, exit or ctrl-C to exit the interpreter
% info tclversion
8.4
% exit
$ expect
expect1.1> info tclversion
8.4
expect1.2> exit 1
Language Overview
• Learning Tcl/Expect - Two parts
– Syntax and Substitution Rules
§ Substitutions simple, may be confusion at first
– Built-in commands
§ Can be learn individually as needed
Data - Strings, Lists
• All Tcl Data are Strings
• All Strings are space separated lists
• i.e. Everything is a “String”, and Every String is a “List”
– This convention was adapted to make the implementation of new Tcl commands in C language much easier, since each C routine only has to deal with one data type i.e. a String
Define a variable – The “set” commands
• Define a Variable
• set varName
• Return Variable Value
set varName
• If varName does not exists, set varName will cause an error
expect1.8> set name
can't read "name": no such variable
while executing
"set name"
expect1.9> set name "gaurav"
gaurav
expect1.10> set name
gaurav
expect1.11>
Language Basics:
• Tcl script =
– Sequence of commands.
– Commands separated by newlines, semi-colons.
• Tcl command =
– One or more words separated by white space.
– First word is command name, others are arguments.
– Returns string result.
• Examples:
set x 22; set y 33
set x 22
set y 33
set y 33
Language Basics (contd.)
• Commands end in newline or semicolon: “\n” or “;”
• Continuation character is backslash: “\”
• Comment the lines/strings using pound sign: “#”
• Recommendations
– Don’t put more then one command on a line
– Indent lines that are continued; 4 spaces are recommended
– The backslash must be the last character on a continued line – not even a space is allowed after a backslash
– Line should not exceed 80 characters
– A comment can be specified after a command
expect1.1> info tclversion
8.3
expect1.2> info \
+> tclversion
8.3
expect1.3> # this is a comment
expect1.4> set v 5 ; info tclversion
8.3
expect1.5> puts $v
5
Variable Substitution:
• Syntax: $varName
• Variable name is letters, digits, underscores.
• May occur anywhere in a word.
Sample command Result
set x 23 23
set y x x
set y $x 23
set y $x+$x 23+23
set y $x.5 23.5
set y $x4 no such variable
• Parser assigns no meaning to arguments
• Different commands assign different meanings to their arguments
Quoting:
• With Square Brackets […]
– Used to pass the return value of a command as an argument to other command; also known as command substitution
• With Double Quotes “…”
– Used to encapsulate the contents of string, with in double or un-quoted string, interpreter will expand:
Example: set x “one two” ; set y “this is $x”
Return: this is one two
• Quoting with Curly Braces {…}
– When quoting with curly braces, no variable, command or backslash subtitution
– “” and {} can be used interchangeably if substitution is not required
Example: set x 5; set y {x=$x;[info tclversion]};
Return: x=$x;[info tclversion]
Expressions:
• C-like (int and double), extra support for string operations.
• Command, variable substitution occurs within expressions.
• Used in expr, other commands.
Sample command Result
set x 5 5
incr x -1 4
expr ($x*4) - 3 13
expr $x <= 2 0
set a cisco cisco
expr {$a < “systems"} 1
Command Substitution:
• Syntax: [script]
• Evaluate script, substitute result.
• May occur anywhere within a word.
Sample command Result
set b 8 8
set a [expr $b+2] 10
set a "b-3 is [expr $b-3]" b-3 is 5
Controlling Word Structure:
• Words break at white space and semi-colons, except:
– Double-quotes prevent breaks:
Set x 3;set y 5; set a "x is $x; y is $y“
Result: x is 3; y is 5
– Curly braces prevent breaks and substitutions:
set a {[expr $b*$c]}
Result: [expr $b*$c]
– Backslashes quote special characters:
set a word\ with\ \$\ and\ space
Result: word with $ and space
• Substitutions don't change word structure:
set a "two words"
set b $a
Result: two words
Tcl Syntax Summary:
• Script = commands separated by newlines or semicolons.
• Command = words separated by white space.
• $ causes variable substitution.
• [] causes command substitution.
• "" quotes white space and semi-colons.
• {} quotes all special characters.
• \ quotes next character, provides C-like substitutions.
• # for comments (must be at beginning of command).
TCL Lists:
• Zero or more elements separated by white space:
Example: set myList “red green blue”
Example: set myList {red green blue}
Result: red green blue
• Braces and backslashes for grouping:
Example: set myList {a b {c d e} f}
Result: a b {c d e} f
• Using the “List” command
Example: set myList [ list red green blue ]
Result: red green blue
• With variable substitution
Example:
set v1 red; set v2 green; set v3 blue
set myList [ list $v1 $v2 $v3 ] Result: red green blue
set myList [ list [ set v1] $v2 $v3 ] Result: red green blue
set myList “$v1 $v2 $v3” Result: red green blue
set myList “[ set v1] $v2 $v3” Result: red green blue
set myList {$v1 $v2 $v3} Result: $v1 $v2 $v3
TCL Lists:
• The “list” manipulation commands allow you to manipulate or query individual elements within the list.
• List Commands:
– list
– lappend
– lindex
– linsert
– llength
– lrange
– lreplace
– lsearch ?mode?
– lsort ?switch?
(switch can be -ascii, -dictionary, -integer, -real, -increasing, -decreasing, -unique etc…)
List Manipulation – Examples
% set list1 { a b c }
a b c
% set list2 { 1 2 3 }
1 2 3
% lappend list1 x y z
a b c x y z
% set list1
a b c x y z
% lindex $list1 4
y
% linsert $list1 4 p q
a b c x p q y z
% llength $list1
6
% lrange $list1 3 end
x y z
% lrange $list1 1 4
b c x y
% lrange $list1 1 2
b c
% lreplace $list1 4 end p q r
a b c x p q r
% lsearch $list1 p
-1
% lsearch $list1 x
3
% lsort $list1
a b c x y z
% lsort -dec $list1
z y x c b a
%
TCL Strings:
• String manipulation commands allow you to work with blocks of characters (strings) within the string
– string compare
– string equal
– string first
– string last
– string index
– string length
– string range |end
– string
– string ?chars?
String Manipulation – Examples:
$ tclsh
% set str1 "cisco"
cisco
% set str2 "systems"
systems
% string compare $str1 $str2
-1
% string equal $str1 $str2
0
% string first is $str1
1
% string first co $str1
3
% string first c $str1
0
% string index $str1 2
s
% string length $str1
5
% string range $str1 2 4
sco
% string range $str1 2 end
sco
% string toupper $str1
CISCO
% string tolower [ string toupper $str1 ]
cisco
% string trim $str1 o
Cisc
Split & Join operations:
• join
- ?joinString?
– Returns a string formed from
- , optionally joined by ?joinString?
• split ?splitChars?
– Returns a list formed from , split at ?splitChars?, is specified
Example:
join { one two three four} . Result: one.two.three.four
split /usr/cisco/bin/tclsh / Result: usr cisco bin tclsh
split cisco {} Result: c i s c o
join {c i s c o } {} Result: cisco
Tcl Arrays:
• Used to group multiple strings together in a single variable
• Specified by a variable name followed by an index enclosed in parentheses.
– set my_array(1) value
– set my_array(one) another_value
• Multidimensional arrays can be simulated
• array names
Returns a list of the indexes for all values stored in the array named
Array Commands
• array set
– Initialize an array
• array names
– Returns all array index
• parray
– Print array
• array unset
– Un-initialize the array
• array exists
– Returns 1 is varName is an array, 0 otherwise
• array size
– Returns number of elements in the array
Tcl Array – Examples
% array set arrayVar \
{ 1 one 2 two 3 three }
% parray arrayVar
arrayVar(1) = one
arrayVar(2) = two
arrayVar(3) = three
% set arrayVar(4) four
four
% parray arrayVar
arrayVar(1) = one
arrayVar(2) = two
arrayVar(3) = three
arrayVar(4) = four
% array names arrayVar
4 1 2 3
% array exists arrayVar
1
% set name gaurav
gaurav
% array exists name
0
% array size arrayVar
4
% array unset arrayVar
% parray arrayVar
"arrayVar" isn't an array
%
Flow Control – if/then/else:
• Basic “if” statement:
set varName 1
if {$varName == 1} { # if expression is true
puts “The expression is true” # execute code
}
• Relational and Logical Operators:
== != < > <= >= && || ( )
• Any expression that returns 0 is “false”; any other value is “true”; 1 is the most common value for true; value must be
• numeric!
• { } Mandatory if expression contains spaces after variable/command substitution
• [ ] Use for command substitution
• ! Negates the result of an expression
• Optional else and elseif , e.g. } else {
• There’s an optional then command, but it’s recommended not to use it
Flow Control – While look:
• Repeatedly evaluate a code block ‘while true’
• Basic “while” statement:
set varName 1
while {$varName < 11} { # while expr is true
puts $varName # execute code
incr varName
}
• Two arguments:
– an expression
– a code block
• The expression is evaluated first
• Watch out for “while 1” loops!
Flow Control – Foreach loop:
• Useful for processing lists
• Basic “foreach” statement:
foreach var [lsort [info commands]] { # set var to next value
puts $var # then, execute code
}
• Three arguments
– the name of a variable to set
– a list to iterate across
– a code block to execute
• Similar to a “while” loop, but it sets a variable to the next value of a list before each invocation of the code block
• The loop terminates when the list contents have been consumed
Flow Control – For loop:
• Specialized “while” loop that combines the processes of initialization, testing, and incrementing into a structure.
• Basic “for” statement:
for {set var 1} {$var < 11} {incr var} {
puts $var # then, execute code
}
• Four arguments:
– an initialization expression (executed once, before 1st loop)
– an expression (evaluated for truth before each loop)
– an ending expression (executed after each loop)
– a code block (the body of the loop)
Include all sections, even if empty
Loop Control – break and continue:
• Basic “break” statement:
while 1{
…
if 1 break; # terminate innermost
…
}
• Basic “continue” statement:
foreach var [info commands] {
if {![string match {l*} $var]} {
continue # go to top of loop
}
puts $var
…
}
Flow Control – While look
• Repeatedly evaluate a code block ‘while true’
• Basic “while” statement:
set varName 1
while {$varName < 11} { # while expr is true
puts $varName # execute code
incr varName
}
• Two arguments:
– an expression
– a code block
• The expression is evaluated first
• Watch out for “while 1” loops!
Keyed List:
• keyed list commands:
• – keyldel
• – keylget
• – keylkeys
• – keylset
• -keylprint
The sample keyed list :
Keylset int gig0/0/0/1.ipv4_address 2.2.2.2
Keylset int gig0/0/0/1.ipv4_mask 255.255.255.0
Keylset int gig0/0/01.admin_status up
Keylset int gig0/0/0/1.link_status up
Sample Keyed List Output:
• # Sample Output:
• # {proc.tcl {
• # {Type User}
• # {Event timer watchdog}
• # {Time Wed Sep 30 05:36:15 2009}
• # {name mywdogtimer}
• # {time_sec 60}
• # {time_nsec 0}
• # {nice 0}
• # {priority normal}
• # {maxrun_sec 20}
• # {maxrun_nsec 0}
• # {persist_time 3600}
• # {username lab}
• # }
# }
Sample Keyed List Output
• expect1.18> keylkeys xyz
• proc_tcl
• expect1.19> keylget xyz proc_tcl
• {Type User}
• {Event timer watchdog}
• {Time Wed Sep 30 05:36:15 2009}
• {name mywdogtimer}
• {time_sec 60}
• {time_nsec 0}
• {nice 0}
• {priority normal}
• {maxrun_sec 20}
• {maxrun_nsec 0}
• {persist_time 3600}
• {username lab}
Regular Expression:
• Metacharacters in the regular expression pattern:
. matches any single character
* matches 0 or more of the previous character(s)
+ matches one or more of the previous character(s)
? matches 0 or 1 occurrences of the previous character(s)
[ chars ] matches any one character in chars
If ] is the first character in chars , it is treated literally
If - appears first or last in chars , it is treated literally
[ ^chars ] matches any one character except those in chars
( ) forms a sub-pattern
| is the or operator; when used, one of the patterns must match
^chars matches chars if chars is at the beginning of a string
chars$ matches chars if chars is at the end of a string
The metacharacters ^ and $ are called anchors when used at the beginning and end of patterns
Regular Expression Pattern Matching:
• Any character other than . [ ] ? + * ^ $ ( ) | matches a single occurrence of that character.
• Examples:
[vV]ersion matches either “version” or “Version”
[0- 9]+ matches a positive integer
(hardware )?address matches either “hardware address” or “address”
hdlc|ppp matches either “hdlc” or “ppp”
. * matches anything, including an empty string
• The backslash character \ escapes the special meaning of the following metacharacter
“regexp” command
“regexp” command:
regexp ?? ?? ? ...?
• The optional variable name will contain the entire substring that matched the expression when regexp returns. The variable names will contain the substrings that match portions of the expression enclosed in parenthesis (()).
• For example:
expect4.1> set string "One: 1, Two: 2, Three: 3"
One: 1, Two: 2, Three: 3
expect4.2> regexp {[Tt]wo: ([0-9]+)} $string match submatch
1
expect4.3> puts $match
Two: 2
expect4.4> puts $submatch
2
expect4.5>regexp {[Tt]wo:.*([0-9]+)} $string match submatch
1
expect4.6>puts $match
Two: 2, Three: 3
expect4.8> puts $submatch
3
Regular Expression Example:
%set string "%invalid Interface E0.\nRouter#"
# Match a string that begins with '%invalid'
%if {[regexp {^%invalid} $string]} {
puts "Validation failed"
}
# Match a string that specifies an ethernet interface
# Expression == The word 'interface' beginning with an upper or lower
# case 'i', followed by a space, and a word beginning with an upper
# or lowercase 'e', an optional , and ending with at least 1 digit
%if {[regexp {[Ii]nterface [Ee][A-Za-z]* ?[0-9]+} $string]} {
puts "Yep, it is an ethernet"
}
%
Regular Expression Example
proc printurl {url} {
set urlmatch {([^:]+)://([^:/]+)(:([0-9]+))?(/.*)}
regexp $urlmatch $url match protocol server x port path
puts "url = $match"
puts "protocol = $protocol"
puts "server = $server"
puts "port = $port"
puts "path = $path"
}
% printurl http://www.cisco.com:80/index.html
url = http://www.cisco.com:80/index.html
protocol = http
server = www.cisco.com
port = 80
path = /index.html
Debugging Regular Expression
• Always check return code!
– If the match fails, regexp will not change the values of the extraction variables. If you don't check the return value, you could be working with data extracted from a previous call to regexp.
• Debug regular expressions interactively, piece by piece
– Cut and paste the pattern into the interpreter
• Use ‘+’ to make sure you have at least one instance of an entire pattern
“regsub” command
• Regular expressions can be used to replace portions of a string with the regsub command:
regsub ??
Switched supported here are all , nocase
* Example:
• set string “Fred Joe bob Steve”
• regsub {bob} $string {Bob} new_string
• STRING MAP :
string map can be used as a alternative to regsub.
expect1.11> set ip 1.1.1.1
expect1.13> string map {. _} $ip
1_1_1_1
expect1.14> set ip ABCDED
expect1.18> string map -nocase {D d} $ip
ABCdEd
expect1.19>
Tcl Procedures
• New commands can be added through Tcl procedure
• “proc” command defines a procedure:
proc
Example:
proc sub1 { x }{ set result [ expr $x-1]; return $result}
Tcl Procedures
• Procedures behave just like built-in commands:
sub1 3 2
• Default return value of the procedure is the value of last expression in the procedure
• Arguments can have defaults:
proc decr {x {y 1}} {
expr $x-$y
}
decr 5 4 1
decr 7 6
• Scoping: local and global variables.
• Tcl Procedures
Variable-length argument lists “args” argument:
Variable-length argument lists “args” argument:
proc sum {args} {
set s 0
set s 0
foreach i $args {
incr s $i
}
return $s
incr s $i
}
return $s
}
%sum 1 2 3 4 5
15
%sum
0
• Procedure provides following benefits
– Easy maintenance – changes needs to be made only at one place
– Saves space, time and effort as a function is implemented only once
– Procedures can be shared when placed in “libraries”
Tcl Procedures:
• Displaying procedure information
– info procs ?? Returns a list of currently defined procedure names
– info args Returns the argument list for procedure
– info body Returns the body of
• proc sub { x { y 1 } } {
• return [ expr $x - $y ]
• }
• % sub 7 3
• 4
• % sub 5
• 4
• % info procs
• auto_load_index unknown auto_import auto_execok auto_qualify auto_load sub history tclLog
• % info args sub
• x y
• % info body sub
• return [ expr $x - $y ]
• %
Global variables
• global varname ?varname ...?
• This command has no effect unless executed in the context of a proc body. If the global command is executed in the context of a proc body, it creates local variables linked to the corresponding global variables
proc accum {string} {
global accumulator
append accumulator $string \n
}
EVAL Command
• eval - Evaluate a Tcl script
• eval arg ?arg ...?
• Eval takes one or more arguments, which together comprise a Tcl script containing one or more commands. Eval concatenates all its arguments in the same fashion as the concat command, passes the concatenated string to the Tcl interpreter recursively, and returns the result of that evaluation (or any error generated by it). Note that the list command quotes sequences of words in such a way that they are not further expanded by the eval command.
EVAL Command (Contd)
• Example:
• set script {
• puts "logging now"
• lappend $myCurrentLogVar }
• set myCurrentLogVar log1
• # Set up a switch of logging variable part way through!
• after 20000
• set myCurrentLogVar log2
• for {set i 0} {$i<10} {incr i} {
• # Introduce a random delay
• after [expr {int(5000 * rand())}] update ;
• # Check for the asynch log switch
• eval $script $i [clock clicks] }
Packages:
• Tcl provides a more powerful mechanism for handling reusable units of code called packages
• A package is simply a bundle of files implementing some functionality, along with a name that identifies the package, and a version number that allows multiple versions of the same package to be present
• A package can be a collection of Tcl scripts, or a binary library, or a combination of both
How to Create Package:
• Adding a package provide statement to your script
• Creating a pkgIndex.tcl file.
• Installing the package where it can be found by Tcl.
• Commands
• package require ?-exact? name ?version?
• package provide name ?version?
Sample Packages:
Example:
package require TclUtils
Tcl Namespaces:
• Tcl namespaces allow you to apply a prefix to a procedure name to avoid overriding procedures in the global namespace with the same name
• Namespaces also allow you to define variables accessible only to procedures within the namespace
• In both cases, namespaces result in reduced namespace collision and remove clutter from the global namespace
The Global Namespace:
• By default, procedures and variables are defined in the global namespace
• Procedures defined in the global namespace are accessible to all other procedures
proc foo {} {puts “hello world”}
proc bar {} {puts [foo]}
proc bar {} {puts [foo]}
• Variables in the global namespace are accessible to procedures via the global command
proc foo {} {
global my_variable
…
}
global my_variable
…
}
• Procedures and variables in the global namespace with the same name overwrite each other (namespace collision)
Defining a Namespace:
• To avoid namespace collision, Tcl library should define all procedures and variables in a private namespace
• Use the Tcl namespace eval command to define a private namespace
namespace eval ::random {
…
}
…
}
• Note: By convension, namespaces have the same name as the package with a lower case first character
Defining Procedures in a Namespace:
• To add a procedure to a namespace, simply precede the name of the procedure with a fully qualified namespace name
proc ::random::get {} {
# Return a random number
}
# Return a random number
}
• Separate the namespace name from the procedure name with double colons
Precede the name with double colons to anchor it in the global namespace (optional
Defining Variables in a Namespace:
• Private variables can be added to a namespace so that they’re accessible to all procedures within the namespace
• This is done by defining the namespace in the namespace eval body and referencing the variable from a procedure using the variable command
namespace eval ::atsdbg {
variable isEnabled 0
}
proc ::atsdbg::enable {} {
variable isEnabled
set result $isEnabled
set isEnabled 1
return $result
}
variable isEnabled 0
}
proc ::atsdbg::enable {} {
variable isEnabled
set result $isEnabled
set isEnabled 1
return $result
}
Procedure and Variable Access:
• To call a procedure defined in a namespace, simply precede the procedure name with the name of it’s namespace
::atsdbg::enable
• To access a variable within a namespace, precede the variable name with the name of the namespace
puts $::atsdbg::isEnabled
• To explicitly access a procedure or variable in the global namespace, precede the name with a double colon
puts $::auto_path
::info tclversion
::info tclversion
No comments:
Post a Comment
Note: only a member of this blog may post a comment.