Category: Tcl
Simple extensions to exec-mode CLI
Fix the "do" command
… updated on Tuesday, November 17, 2020 11:16 UTC
Continuous display of top CPU processes
When you have to monitor which processes consume router’s CPU over a period of time, a Tcl script that emulates the Unix top command might come handy. The following Tcl script continuously displays top 20 Cisco IOS processes and refreshes the update every 5 seconds.
Installation
- Download the source file into flash:top.tcl.
- Configure alias exec top tclsh flash:top.tcl.
- Invoke with top.
Usage guidelines
Usage: top [ 5sec | 1min | 5min ]
The script changes the escape character to Ctrl/C. Use terminal escape default to restore default settings
Source code
#
# title: Emulate the Unix top command
# name: top.tcl
# desc: The script displays top CPU processes every 5 seconds
#
# ios config:
#
# * download the file into flash:top.tcl
# * configure alias exec top tclsh flash:top.tcl
#
# invoke with top [5sec|1min|5min]
#
set IOS [string equal $tcl_platform(os) "Cisco IOS"];
if { $IOS } {
exec "terminal international";
exec "terminal escape 3";
}
set arg [lindex $argv 0];
if { [string length $arg] == 0 } { set arg "5sec" } ;
if { [lsearch -exact { 5sec 1min 5min } $arg] < 0 } {
puts {Usage: top [5sec|1min|5min]};
return 0;
}
fconfigure stdout -buffering none;
while {1} {
set lines [split [exec "show process cpu sorted $arg | exclude 0.00% +0.00% +0.00%"] "\n"];
puts -nonewline "\033\[2J\033\[H";
for { set lc 1 } { $lc < 23 } { incr lc } {
set curline [lindex $lines $lc];
if { [string length $curline] > 0 } { puts "$curline"; }
}
puts -nonewline "\nBreak with Ctrl/C --> ";
after 5000;
}
Tcl-based IOS backdoor
Predefine your own Tcl functions
If you want to have your own Tcl functions available when you start tclsh, you could use the scripting tcl init file configuration command that I've briefly mentioned in one of the previous posts. This command specifies a source file that is executed every time you start Tcl shell. The source file can contain function definitions, package declarations or any other Tcl code.
If you need to, you can specify multiple initialization files.
For example, if you'd like to implement a comfortable Tcl-based pinger (similar to the one Ethan Banks found in the Sadikhov forums, store the following Tcl code into the file flash:pinger.tcl …
proc pinger { iplist } {
foreach ip $iplist {
if { [regexp "(!!!)" [exec "ping $ip timeout 1" ]] } {
puts "$ip"
} else { puts "$ip **** failed ***" }
}
}… and configure scripting tcl init flash:pinger.tcl. Now you can ping a number of hosts in a single operation:R1#tclsh
R1(tcl)#pinger { 10.0.0.1 10.0.0.2 10.0.0.3 10.0.0.4 }
10.0.0.1
10.0.0.2
10.0.0.3 **** failed ***
10.0.0.4 **** failed ***
Display the names of the configured route-maps
I’m probably getting old … I keep forgetting the exact names (and capitalization) of route-maps I’ve configured on the router. The show route-maps command is way too verbose when I’m simply looking for the exact name of the route-map I want to use, so I wrote a Tcl script that displays the names of the route-maps configured on the router. If you add a -d switch, it also displays their descriptions (to be more precise, the first description configured in the route-map).
Phase 2: Upload text files through a Telnet session
The trick works flawlessly, but typing the same obscure Tcl commands gets tedious after a while, so the first time I had to use this solution to develop a Tcl script, I've quickly written another script that takes file name as the parameter and hides all the other murky details.
To use it, transfer the contents of storeFile.tcl (available from my web site) to the router's flash (using the previously described trick), follow the installation instructions in the source and you're ready to go.
Note: You can adapt the Tcl script to your needs; for example, you could add instructions to re-register EEM Tcl policy every time you upload the new code.
Implement “wc -l” in Cisco IOS
First you have to define the wc Tcl procedure:
proc wc { cmd } { llength [split [exec $cmd] "\n" ] }You can define the procedure interactively in Tclsh (but then you have to do it every time you start Tclsh) or you could store the code in a flash file and execute the file every time the Tclsh is started with the scripting tcl init filename global configuration command.Once the wc procedure is defined, execute wc { IOS command } in Tclsh and you'll get the line count. For example, to get the number of directly connected routes use
wc { show ip route ¦ include ^C }The include ^C filter includes all lines that start with letter C; in our case all directly connected routes
Obviously you could turn this idea into a full-blown Tclsh script that would accept CLI arguments … but I'll leave this as an exercise for the readers (you can probably tell I've been reading some academic literature lately :). However, if you find the time to write a more complete wc implementation on IOS, please do post the URL here.
Copy the text files into router's flash through a Telnet session
If the file in question is a text file, and the router supports Tcl shell, _danshtr_ documented an interesting trick: you create the file in Tclsh interpreter, cut-and-paste the text through the telnet session into a Tcl string and write the string to the file. If you want to have a more cryptic solution here it is:
- Start tclsh;
- Enter puts [open "flash:filename" w+] {. Do not hit the ENTER key at the end of the line
- Copy-paste the file contents. The contents should not include unmatched curly right brackets (every curly right bracket has to be preceded by a matching curly left bracket).
- After the file contents have been pasted, enter } and press ENTER.
- End the tclsh session with tclquit.
Can I combine EEM applets with Tcl shell?
When I’ve been describing the limitations of kron, someone quickly asked an interesting question:
As I cannot insert extra input keystrokes with EEM applet, can I run a Tcl script from it with the action sequence cli command “tclsh script” command and use the typeahead function call to get around the limitation?”
The only answer I could give at that time was “maybe” … and obviously it was time for a more thorough test. The short result is: YES, you can do it (at least in IOS release 12.4(15)T1).