cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
5342
Views
5
Helpful
7
Replies

How to run TcL Scripts from EEM

Cory Anderson
Level 1
Level 1

Hi everyone!

I have some TcL scripts that run fine from tclsh, but I'm not sure how to trigger them from EEM.

Any help would be greatly appreciated. 

Here's an example...If I don't use the ::cisco::eem...., or namespace import, the rest of .tcl file runs fine.  I realize this script doesn't really require tcl, but I'm using it to get the concept of running a *.tcl file from eem.

 

Example

########################################################

::cisco::eem::event_register_syslog pattern {ip sla 1 state Down->Up}


namespace import ::cisco::eem::*
namespace import ::cisco::lib::*

set HOSTNAME [lindex [exec "show run | i ^hostname"] 1]
set SERVER "10.0.0.20"
set USER "admin"
set PASSWORD "password"

exec "copy run scp://$USER:$PASSWORD@$SERVER/$HOSTNAME.cfg"

#########################################################

BACKUP_WHEN_UP.tcl: invalid command name "exec"
000045: Aug 24 22:11:20.519 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl:     while executing

2 Accepted Solutions

Accepted Solutions

Joe Clarke
Cisco Employee
Cisco Employee

You cannot use exec in EEM Tcl.  You would need to replace it with:

 

if { [catch {cli_open} result] } {

    exit 1

}

 

array set cli $result

 

cli_exec $cli(fd) "enable"

cli_exec $cli(fd) "copy run scp://$USER:$PASSWORD@$SERVER/$HOSTNAME.cfg"

 

catch {cli_close $cli(fd) $cli(tty_id)}

View solution in original post

The copy command appears to be interactive.  You'll need to answer the prompts or disable them (if you can) in order for this to work.  Depending on the prompt, you may be able to disable it by configuring "file prompt quiet".  Else, you'll need to change cli_exec to cli_write, then follow that up with cli_read_pattern:

 

cli_write $cli(fd) "copy ..."

cli_read_pattern $cli(fd) "confirm"

cli_write $cli(fd) "\r"

 

Where "confirm" is a string within the prompt.  The following cli_write command should provide the answer to the prompt (whatever it may be).

View solution in original post

7 Replies 7

Joe Clarke
Cisco Employee
Cisco Employee

You cannot use exec in EEM Tcl.  You would need to replace it with:

 

if { [catch {cli_open} result] } {

    exit 1

}

 

array set cli $result

 

cli_exec $cli(fd) "enable"

cli_exec $cli(fd) "copy run scp://$USER:$PASSWORD@$SERVER/$HOSTNAME.cfg"

 

catch {cli_close $cli(fd) $cli(tty_id)}

Hi Joe, I really appreciate your help!

I did try this & I keep getting max run timeouts...  Here's the script, with exec removed.  I event simlified it to not use some of the variables thinking that was the issue.  

 

Do you mind giving me a little more indicator of what I'm missing?  Again, your help is really appreciated & beneficial.

 

::cisco::eem::event_register_syslog pattern {ip sla 1 state Down->Up}


namespace import ::cisco::eem::*
namespace import ::cisco::lib::*

array set rn [sys_reqinfo_routername]
set HOSTNAME $rn(routername)
#set SERVER "10.0.0.23"
#set USER "admin"
#set PASSWORD "password"

if { [catch {cli_open} result] } {
    exit 1
}
 
array set cli $result
 
cli_exec $cli(fd) "enable"
#cli_exec $cli(fd) "copy run scp://$USER:$PASSWORD@$SERVER/$HOSTNAME.cfg"
cli_exec $cli(fd) "copy run scp://admin:password@10.0.0.23/test.cfg"
 
catch {cli_close $cli(fd) $cli(tty_id)}

 

************************************

logs,

000182: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: Process Forced Exit- MAXRUN timer expired.
000183: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl:     while executing
000184: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: "if [catch {cli_read $fd} result] {
000185: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl:         return -code error "error reading the channel: $result"
000186: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl:     } else {
000187: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl:         return $result
000188: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl:     }"
000189: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl:     (procedure "cli_exec" line 4)
000190: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl:     invoked from within
000191: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: "cli_exec $cli(fd) "copy run scp://admin:password@10.0.0.23/test.cfg""
000192: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl:     invoked from within
000193: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: "$slave eval $Contents"
000194: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl:     (procedure "eval_script" line 7)
000195: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl:     invoked from within
000196: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: "eval_script slave $scriptname"
000197: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl:     invoked from within
000198: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: "if {$security_level == 1} {       #untrusted script
000199: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl:      interp create -safe slave
000200: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl:      interp share {} stdin slave
000201: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl:      interp share {} stdout slave
000202: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: ..."
000203: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl:     (file "tmpsys:/lib/tcl/base.tcl" line 50)
000204: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: Tcl policy execute failed:
000205: Aug 26 04:20:34.731 UTC: %HA_EM-6-LOG: BACKUP_WHEN_UP.tcl: Process Forced Exit- MAXRUN timer expired.

 

 

The copy command appears to be interactive.  You'll need to answer the prompts or disable them (if you can) in order for this to work.  Depending on the prompt, you may be able to disable it by configuring "file prompt quiet".  Else, you'll need to change cli_exec to cli_write, then follow that up with cli_read_pattern:

 

cli_write $cli(fd) "copy ..."

cli_read_pattern $cli(fd) "confirm"

cli_write $cli(fd) "\r"

 

Where "confirm" is a string within the prompt.  The following cli_write command should provide the answer to the prompt (whatever it may be).

Thanks Joe!  That was it.  Here's my results:

::cisco::eem::event_register_syslog pattern {ip sla 1 state Down->Up}

namespace import ::cisco::eem::*
namespace import ::cisco::lib::*

array set rn [sys_reqinfo_routername]
set HOSTNAME $rn(routername)
set SERVER "10.0.0.23"
set USER "admin"
set PASSWORD "password"

if { [catch {cli_open} result] } {
    exit 1
}
 
array set cli $result
 
cli_exec $cli(fd) "enable"
cli_exec $cli(fd) "configure terminal"
cli_exec $cli(fd) "file prompt quiet"
cli_exec $cli(fd) "end"
cli_exec $cli(fd) "enable"
cli_exec $cli(fd) "copy run scp://$USER:$PASSWORD@$SERVER/$HOSTNAME.cfg"
cli_exec $cli(fd) "configure terminal"
cli_exec $cli(fd) "no file prompt quiet"
cli_exec $cli(fd) "end"

catch {cli_close $cli(fd) $cli(tty_id)}

Cory Anderson
Level 1
Level 1

Thanks Joe!

Do set commands still work?  I'll give this a shot.

~Cory Anderson

Yes, set still works.  But exec needs to be done using the CLI handle.  And the hostname can be obtained using:

 

array set rn [sys_reqinfo_routername]

set HOSTNAME $rn(routername)
 

mario.jost
Level 3
Level 3

Another thing you could do if you already have the TCL script, is run it directly from within the event manager applet. That way you dont have to rewrite everyting into cli_open and can just use exec as you are used to. We run scripts alot on our devices that way:

event manager applet RUNTCLSCRIPT
  event timer cron cron-entry "0 2 * * *" maxrun 1800
  action 001 cli command "enable"
  action 002 cli command "tclsh flash:/company/scripts/alias.tcl arg1 arg2"

You can also point directly to a central TFTP or HTTP source so you do not have to store the scripts locally. Hope this helps someone else in the future that stumbles over this thread.

Review Cisco Networking for a $25 gift card