Building network automation solutions

9 module online course

Start now!

Category: Tcl

Using Tcl packages on Cisco IOS

Although it's not exactly trivial, you can use standard Tcl packages with Tcl
shell on Cisco IOS by following this procedure:

$ tclsh
% pkg_mkIndex . *.tcl
% ^Z
  • Edit the pkgIndex.tcl file created with the pkg_mkIndex command and set the $dir variable to the IOS directory before the first package command (for example, set dir "flash:tcl/").
  • Alternatively, add the Tcl command set dir [file dirname [info script]] in front of the first package command. This command sets the $dir variable to the path of the pkgIndex.tcl file.
  • Transfer all the source files into a directory on the router's flash (or any other local storage device).
  • Configure the execution of the pkgIndex.tcl file at tclsh startup with the scripting tcl init configuration command (for example, scripting tcl init flash:tcl/pkgIndex.tcl).

When you have completed these steps, the pkgIndex.tcl file will be executed every time the Tcl shell is started in Cisco IOS, defining all the packages you've prepared. Now you can use the package require name Tcl command to load the packages you need in your Tcl script.

see 2 comments

Reload a router from Tcl script

In his comment, Michal has asked about the ability to execute IOS commands with prompts from Tcl shell. I haven't found a generic solution yet, but you can reload a router from a Tcl script. First you have to define an EEM applet that reloads the router and can be triggered from command-line interface:
event manager applet forceReload
event none
action 1.0 reload
Now you can use the exec "event manager run forceReload" Tcl command in your Tcl script to run the applet (and reload the router).


see 2 comments

In-depth presentation on Tcl, EEM, ERM, Kron ...

The comment made by Xavier sent me searching the Cisco documentation for the scripting tcl low-memory command. While I was not able to find anything useful (even links to some other scripting commands point to nowhere), I've discovered this gem - a great presentation explaining Tcl, EEM, ESM, ERM and Kron. Highly recommended reading :)

Update @ 2009-03-05: fixed the link to the presentation
see 3 comments

You fix some, you break some ...

When Cisco fixed the tclsh bug in IOS release 12.4, they managed to break another nice feature: you can no longer execute tcl scripts within HTTP server on Cisco IOS. Previously you could use tcl scripts to generate customized outputs or reports that could be viewed through a web browser or even generate parts of HTML code that could be included in web pages served from the router. It's all gone in 12.4(15)T1 ...
add comment

Example: Tcl script with command-line parameters

In a comment to the “Execute multiple commands at once” post, Michal has asked for a complete Tcl-shell-with-parameter example. Here's a short script that shuts down the interface and displays its status:

  • Variable ifname is set to the value of the first command-line parameter (in many other programming languages, this would be written as argv[0]);
  • If the ifname is empty, the script aborts and prints the usage guidelines (again, in a more human-oriented programming language, this would be if (ifname == “”) ...);
  • The show ip interface ifname command is executed. If it fails, the interface name is not correct and the script aborts.
  • IOS configuration commands interface ifname and shutdown are executed.
  • The show ip interface brief configuration command is executed and filtered with the interface name.
# ifname is set to first CLI parameter (interface name)
set ifname [lindex $argv 0]
if {[string equal $ifname ""]} { puts "Usage: shutdown ifname"; return; }
if { [ catch { exec "show ip interface $ifname" } errmsg ] } {
puts "Invalid interface $ifname, show ip interface failed"; return}

ios_config "interface $ifname" "shutdown"
puts [ exec "show ip interface brief ¦ include $ifname" ]

If you store this Tcl script into your flash as shutdown.tcl and configure alias exec shutdown tclsh flash:shutdown.tcl, you can execute the command shutdown Serial0 to shut down the serial interface.


  • The last show command will display the interface status only if the specified interface name exactly matches the actual IOS interface name (whereas the rest of the script accepts shortcut names). The more generic matching algorithm is left as an exercise for the reader
  • For more in-depth information on Tclsh implementation on Cisco IOS, read the IOS Tclsh resources.
  • This article is part of You've asked for it series.
see 10 comments

Update: The “show ip interface” command I've always wanted to have

After I've published the Tcl script that displays the interface IP parameters in a formatted table, cos quickly pointed out a bug: I've expected the IP addresses in the address mask format. In the meantime, I've figured out the root cause of the problem (our remote labs are set to display IP masks in decimal format for compatibility reasons) and fixed the Tcl script. It temporarily sets the terminal ip netmask-format to bit-count before executing the show command. The new script recognizes three parameters:

  • active: display only interfaces that are up/up;

  • configured: display only interfaces with configured IP addresses (unnumbered interfaces using IP address of an interface without one count as configured since IOS reports their IP address as

  • address: displays IP address of the unnumbered interface, not the interface that it's borrowing the address from.
You can view the Tcl source or download it from my web site.
see 6 comments

The “show ip interface” command I've always wanted to have

Recently I was investigating MTU-related problems and got mightily upset when I had to search for the interface IP MTU size in the long printout produced by the show ip interface command. Obviously I could display the IP MTU size of a single interface with the show ip interface name | include MTU filter, but I wanted to have a nice tabular printout. Obviously it was time for another Tcl script.

To use it, download it and store it into the flash memory of your router. Configure alias exec ipconfig tclsh flash:ipInterfaces.tcl and you can use ipconfig or ipconfig active to display interface IP addresses.
read more see 5 comments

Reload EEM Tcl policy with help of Tcl shell

Testing Embedded Event Manager (EEM) Tcl policies is a convoluted process:
  • Source file is usually edited on a general-purpose workstation.
  • The file has to be downloaded to router's local storage (EEM does not register non-local policies).
  • The new version of the EEM policy has to be registered with EEM with event manager policy configuration command
  • After all these steps, the new policy can be tested.
While you can use EEM applet to automate this process, slightly more flexible approach (you can specify the policy name to be replaced) can be implemented with Tcl script:
set policy [lindex $argv 0]
set source "tftp://" # replace with your host and directory
set destination "nvram:" # replace with local storage device
if {[string equal $policy ""]} {
return -code error "expected policy name"
puts "replacing policy: $policy"
ios_config "file prompt quiet"
ios_config "no event manager policy $policy" ""
exec "copy $source$policy $destination$policy"
ios_config "event manager policy $policy"
ios_config "no file prompt quiet"
To use the script, follow these steps:
  • Save the script in a .tcl file (for example, changePolicy.tcl)
  • Change the script parameters (remote host and local storage)
  • Save the .tcl file to your router's local storage (you can also run it from a remote server)
  • Configure a command alias, for example alias exec eem tclsh flash:changePolicy.tcl testPolicy.tcl
Now you can replace the target EEM Tcl policy with a simple eem command.

Alternatively, if you define alias exec eem tclsh flash:changePolicy.tcl, you can specify policy name as an argument to the eem command, for example eem testPolicy.tcl.
see 1 comments

Command Authorization Fails with EEM applet or Tcl policy

One of my readers asked an interesting question: „why do the commands executed within a EEM Tcl policy fail with Command authorization fails message?“ The short answer is simple: If you use AAA command authorization (which you can only do if you're using a TACACS+ server), you have to specify the username under which the EEM will execute its CLI commands with the event manager session cli username user configuration command.

read more see 8 comments

Use Tcl script to change the interface status

During network troubleshooting or proof-of-concept testing, I often change the state of a loopback interface (to insert or remove IP prefix from the routing protocols) or flap it to test the impact on network stability. The traditional approach to this procedure should be known to everyone:
  • Enter configuration mode;
  • Select the appropriate interface with the interface loopback x command;
  • Try to remember whether you need to disable or enable it;
  • Issue the shutdown or no shutdown command;
  • Exit the configuration mode and continue your debugging/testing process.

After a particularly boring testing session I decided to write a Tcl script to automate the job. To use it, download it and store it into ifchange.tcl. Download the Tcl file to your router (Flash or NVRAM) and define an alias: alias exec ifchange tclsh flash:ifchange.tcl. Now you can use the new ifchange command to change interface status.

read more see 2 comments

IOS Tclsh resources

Before trying to write Tcl procedures to be executed by Cisco IOS tclsh command, read the following articles:

And last but not least, if you want to store Tcl procedures on your router and don't want to write into the router's Flash memory (I hate that the router prompts me whether I want to erase the flash every time I store something into it), you can store them in NVRAM.

add comment

Executing IOS commands from Tcl shell

The Tcl procedures used to execute IOS commands in Embedded Event Manager (cli_open, cli_write …) don’t work when you start Tcl shell from command line interface. To execute IOS commands in this context, use:

  • exec command to execute an exec-level command, for example exec “show ip route”
  • ios_config mode command to configure the router

If the first parameter of the ios_config command is a global configuration command, you shall omit the second parameter (for example, ios_config “hostname router”). To configure a parameter in one of the sub-configuration modes (for example, interface state), use the first parameter to specify the configuration mode and the second parameter as the actual configuration command (for example, ios_config “interface loop 0” “no shutdown”).

add comment