- Embedded Event Manager Overview
- Writing Embedded Event Manager Policies Using the Cisco IOS CLI
- Writing Embedded Event Manager Policies Using Tcl
- EEM Action Tcl Command Extension
- EEM CLI Library Tcl Command Extensions
- EEM CLI Library XML-PI Tcl Support
- EEM Context Library Tcl Command Extensions
- EEM Event Registration Tcl Command Extensions
- EEM Event Tcl Command Extensions
- EEM Library Debug Tcl Command Extensions
- EEM Multiple Event Support Tcl Command Extensions
- EEM SMTP Library Tcl Command Extensions
- EEM System Information Tcl Command Extensions
- EEM Utility Tcl Command Extensions
EEM CLI Library Command Extensions
All command-line interface (CLI) library command extensions belong to the ::cisco::eem namespace.
This library provides users the ability to run CLI commands and get the output of the commands in Tcl. Users can use commands in this library to spawn an exec and open a virtual terminal channel to it, write the command to execute to the channel so that the command will be executed by exec, and read back the output of the command.
There are two types of CLI commands: interactive commands and non-interactive commands.
For interactive commands, after the command is entered, there will be a "Q&A" phase in which the router will ask for different user options, and the user is supposed to enter the answer for each question. Only after all the questions have been answered properly will the command run according to the user's options until completion.
For noninteractive commands, once the command is entered, the command will run to completion. To run different types of commands using an EEM script, different CLI library command sequences should be used, which are documented in the "Using the CLI Library to Run a Noninteractive Command" section and in the "Using the CLI Library to Run an Interactive Command" section in the cli_write Tcl command.
The vty lines are allocated from the pool of vty lines that are configured using the line vty CLI configuration command. EEM will use a vty line when a vty line is not being used by EEM and there are available vty lines. EEM will also use a vty line when EEM is already using a vty line and there are three or more vty lines available. Be aware that the connection will fail when fewer than three vty lines are available, preserving the remaining vty lines for Telnet use.
In Cisco IOS Release 12.4(22)T, and later releases, XML-PI support was introduced. For details about the XML-PI support, the new CLI library command extensions, and some examples of how to implement XML-PI, see EEM CLI Library XML-PI Support.
cli_close
Closes the exec process and releases the vty and the specified channel handler connected to the command-line interface (CLI).
Syntax
cli_close fd tty_id
Arguments
fd |
(Mandatory) The CLI channel handler. |
tty_id |
(Mandatory) The TTY ID returned from the cli_open command extension. |
Result String
None
Set _cerrno
Cannot close the channel.
cli_exec
Writes the command to the specified channel handler to execute the command. Then reads the output of the command from the channel and returns the output.
Syntax
cli_exec fd cmd
Arguments
fd |
(Mandatory) The command-line interface (CLI) channel handler. |
cmd |
(Mandatory) The CLI command to execute. |
Result String
The output of the CLI command executed.
Set _cerrno
Error reading the channel.
cli_get_ttyname
Returns the real and pseudo TTY names for a given TTY ID.
Syntax
cli_get_ttyname tty_id
Arguments
tty_id |
(Mandatory) The TTY ID returned from the cli_open command extension. |
Result String
pty %s tty %s
Set _cerrno
None
cli_open
Allocates a vty, creates an EXEC command-line interface (CLI) session, and connects the vty to a channel handler. Returns an array including the channel handler.
Note |
Each call to cli_open initiates a Cisco IOS EXEC session that allocates a Cisco IOS vty line. The vty remains in use until the cli_close routine is called. The vty lines are allocated from the pool of vty lines that are configured using the line vty CLI configuration command. EEM will use a vty line when a vty line is not being used by EEM and there are available vty lines. EEM will also use a vty line when EEM is already using a vty line and there are three or more vty lines available. Be aware that the connection will fail when fewer than three vty lines are available, preserving the remaining vty lines for Telnet use |
Syntax
cli_open
Arguments
None
Result String
"tty_id {%s} pty {%d} tty {%d} fd {%d}"
Event Type |
Description |
---|---|
tty_id |
TTY ID. |
pty |
PTY device name. |
tty |
TTY device name. |
fd |
CLI channel handler. |
Set _cerrno
- Cannot get pty for EXEC.
- Cannot create an EXEC CLI session.
- Error reading the first prompt.
cli_read
Reads the command output from the specified command-line interface (CLI) channel handler until the pattern of the router prompt occurs in the contents read. Returns all the contents read up to the match.
Syntax
cli_read fd
Arguments
fd |
(Mandatory) The CLI channel handler. |
Result String
All the contents read.
Set _cerrno
Cannot get router name.
Note |
This Tcl command extension will block waiting for the router prompt to show up in the contents read. |
cli_read_drain
Reads and drains the command output of the specified command-line interface (CLI) channel handler. Returns all the contents read.
Syntax
cli_read_drain fd
Arguments
fd |
(Mandatory) The CLI channel handler. |
Result String
All the contents read.
Set _cerrno
None
cli_read_line
Reads one line of the command output from the specified command-line interface (CLI) channel handler. Returns the line read.
Syntax
cli_read_line fd
Arguments
fd |
(Mandatory) The CLI channel handler. |
Result String
The line read.
Set _cerrno
None
Note |
This Tcl command extension will block waiting for the end of line to show up in the contents read. |
cli_read_pattern
Reads the command output from the specified command-line interface (CLI) channel handler until the pattern that is to be matched occurs in the contents read. Returns all the contents read up to the match.
Note |
The pattern matching logic attempts a match by looking at the command output data as it is delivered from the Cisco IOS command. The match is always done on the most recent 256 characters in the output buffer unless there are fewer characters available, in which case the match is done on fewer characters. If more than 256 characters in the output buffer are required for the match to succeed, the pattern will not match. |
Syntax
cli_read_pattern fd ptn
Arguments
fd |
(Mandatory) The CLI channel handler. |
ptn |
(Mandatory) The pattern to be matched when reading the command output from the channel. |
Result String
All the contents read.
Set _cerrno
None
Note |
This Tcl command extension will block waiting for the specified pattern to show up in the contents read. |
cli_run
Iterates over the items in the clist and assumes that each one is a command-line-interface (CLI) command to be executed in the enable mode. On success, returns the output of all executed commands and on failure, returns error from the failure.
Syntax
cli_run clist
Arguments
clist |
(Mandatory) The list of commands to be executed. |
Result String
Output of all the commands that are executed or an error message.
Set _cerrno
None.
Sample Usage
The following example shows how to use the cli_run command extension.
set clist [list {sh run} {sh ver} {sh event man pol reg}] cli_run { clist }
cli_run_interactive
Provides a sublist to the clist which has four items. On success, returns the output of all executed commands and on failure, returns error from the failure. Also uses arrays when possible as a way of making things easier to read later by keeping expect and reply separated.
Syntax
cli_run_interactive clist
Arguments
Result String
Output of all the commands that are executed or an error message.
Set _cerrno
None.
Sample Usage
The following example shows how to use the cli_ru_ interactive command extension.
set cmd1 "first command" set cmd1_exp1 {[confirm]} set cmd1_rep1 {y} set cmd1_response [list [list expect $cmd1_exp1 reply $cmd1_rep1]] set cmd2 "second command" set cmd2_exp1 {save config} set cmd2_rep1 {no} set cmd2_exp2 {[confirm]} set cmd2_rep2 {y} set cmd2_response [list [list expect $cmd2_exp1 reply $cmd2_rep1] [list expect $cmd2_exp2 reply $cmd2_rep2]] set cmd3 "third command" set cmd3_exp1 {are you sure} set cmd3_rep1 {yes} set cmd3_exp2 {destination file} set cmd3_rep2 {test.txt} set cmd2_response [list [list expect $cmd3_exp1 reply $cmd3_rep1] [list expect $cmd3_exp2 reply $cmd3_rep2]] set clist [list " command $cmd1 responses $cmd1_response" " command $cmd2 responses $cmd2_response" " command $cmd3 responses $cmd3_response"] cli_run_interactive { clist }
cli_write
Writes the command that is to be executed to the specified CLI channel handler. The CLI channel handler executes the command.
Syntax
cli_write fd cmd
Arguments
fd |
(Mandatory) The CLI channel handler. |
cmd |
(Mandatory) The CLI command to execute. |
Result String
None
Set _cerrno
None
Sample Usage
As an example, use configuration CLI commands to bring up Ethernet interface 1/0:
if [catch {cli_open} result] { puts stderr $result exit 1 } else { array set cli1 $result } if [catch {cli_exec $cli1(fd) "en"} result] { puts stderr $result exit 1 } if [catch {cli_exec $cli1(fd) "config t"} result] { puts stderr $result exit 1 } if [catch {cli_exec $cli1(fd) "interface Ethernet1/0"} result] { puts stderr $result exit 1 } if [catch {cli_exec $cli1(fd) "no shut"} result] { puts stderr $result exit 1 } if [catch {cli_exec $cli1(fd) "end"} result] { puts stderr $result exit 1 } if [catch {cli_close $cli1(fd) $cli1(tty_id)} } result] { puts stderr $result exit 1
Using the CLI Library to Run a Noninteractive Command
To run a noninteractive command, use the cli_exec command extension to issue the command, and then wait for the complete output and the router prompt. For example, the following shows the use of configuration CLI commands to bring up Ethernet interface 1/0:
if [catch {cli_open} result] { error $result $errorInfo } else { set fd $result } if [catch {cli_exec $fd "en"} result] { error $result $errorInfo } if [catch {cli_exec $fd "config t"} result] { error $result $errorInfo } if [catch {cli_exec $fd "interface Ethernet1/0"} result] { error $result $errorInfo } if [catch {cli_exec $fd "no shut"} result] { error $result $errorInfo } if [catch {cli_exec $fd "end"} result] { error $result $errorInfo } if [catch {cli_close $fd} result] { error $result $errorInfo }
Using the CLI Library to Run an Interactive Command
To run interactive commands, three phases are needed:
- Phase 1: Issue the command using the cli_write command extension.
- Phase 2: Q&A Phase. Use the cli_read_pattern command extension to read the question (the regular pattern that is specified to match the question text) and the cli_write command extension to write back the answers alternately.
- Phase 3: Noninteractive phase. All questions have been answered, and the command will run to completion. Use the cli_read command extension to wait for the complete output of the command and the router prompt.
For example, use CLI commands to do squeeze bootflash: and save the output of this command in the Tcl variable cmd_output.
if [catch {cli_open} result] { error $result $errorInfo } else { array set cli1 $result } if [catch {cli_exec $cli1(fd) "en"} result] { error $result $errorInfo } # Phase 1: issue the command if [catch {cli_write $cli1(fd) "squeeze bootflash:"} result] { error $result $errorInfo } # Phase 2: Q&A phase # wait for prompted question: # All deleted files will be removed. Continue? [confirm] if [catch {cli_read_pattern $cli1(fd) "All deleted"} result] { error $result $errorInfo } # write a newline character if [catch {cli_write $cli1(fd) "\n"} result] { error $result $errorInfo } # wait for prompted question: # Squeeze operation may take a while. Continue? [confirm] if [catch {cli_read_pattern $cli1(fd) "Squeeze operation"} result] { error $result $errorInfo } # write a newline character if [catch {cli_write $cli1(fd) "\n"} result] { error $result $errorInfo } # Phase 3: noninteractive phase # wait for command to complete and the router prompt if [catch {cli_read $cli1(fd) } result] { error $result $errorInfo } else { set cmd_output $result } if [catch {cli_close $cli1(fd) $cli1(tty_id)} result] { error $result $errorInfo }
The following example causes a router to be reloaded using the CLI reload command. Note that the EEM action_reload command accomplishes the same result in a more efficient manner, but this example is presented to illustrate the flexibility of the CLI library for interactive command execution.
# 1. execute the reload command if [catch {cli_open} result] { error $result $errorInfo } else { array set cli1 $result } if [catch {cli_exec $cli1(fd) "en"} result] { error $result $errorInfo } if [catch {cli_write $cli1(fd) "reload"} result] { error $result $errorInfo } else { set cmd_output $result } if [catch {cli_read_pattern $cli1(fd) ".*(System configuration has been modified. Save\\\? \\\[yes/no\\\]: )"} result] { error $result $errorInfo } else { set cmd_output $result } if [catch {cli_write $cli1(fd) "no"} result] { error $result $errorInfo } else { set cmd_output $result } if [catch {cli_read_pattern $cli1(fd) ".*(Proceed with reload\\\? \\\[confirm\\\])"} result] { error $result $errorInfo } else { set cmd_output $result } if [catch {cli_write $cli1(fd) "y"} result] { error $result $errorInfo } else { set cmd_output $result } if [catch {cli_close $cli1(fd) $cli1(tty_id)} result] { error $result $errorInfo }