cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
1544
Views
0
Helpful
12
Replies
Beginner

Interactive commands

I've written a very simple script today... Basically the whole idea is to use the cli_run_interactive command from the EEM cli library extensions. According to this document

http://www.cisco.com/en/US/docs/ios-xml/ios/eem/configuration/xe-3se/5700/eem-cli-library-tcl.pdf

I have to use the ::cisco::eem:: namespace, which I did. Then, again from the same document I found the command cli_run_interactive which does exactly what I need, to execute a command, watch for a predefined command output and react on it, again in a predefined way. Pretty straight forward. Below the script:

::cisco::eem::event_register_none maxrun 36

namespace import ::cisco::eem::*

namespace import ::cisco::lib::*

set cmd1 "clear line 46"

set cmd1_exp1 {[confirm]}

set cmd1_rep1 {y}

set cmd1_response [list [list expect $cmd1_exp1 reply $cmd1_rep1]]

set clist [list " command $cmd1 responses $cmd1_response"]

cli_run_interactive { clist }

So far, so good, I register the script:

Terminal#show runn | sec event manager

event manager directory user policy flash:/

event manager policy run_interactive.tcl type user

Terminal#show event manager policy registered

No.  Class   Type    Event Type          Trap  Time Registered           Name

1    script  user    none                Off   Tue Oct 8 17:19:04 2013   run_interactive.tcl

policyname {run_interactive.tcl}

nice 0 queue-priority normal maxrun 36.000

But then, when I try to execute the script:

Terminal#event manager run run_interactive.tcl

Terminal#invalid command name "cli_run_interactive"

    while executing

"cli_run_interactive { clist }"

    invoked from within

"$slave eval $Contents"

    (procedure "eval_script" line 7)

    invoked from within

"eval_script slave $scriptname"

    invoked from within

"if {$security_level == 1} {       #untrusted script

     interp create -safe slave

     interp share {} stdin slave

     interp share {} stdout slave

..."

    (file "system:/lib/tcl/base.tcl" line 50)

Tcl policy execute failed: invalid command name "cli_run_interactive"

So it seems to me I've missed a declaration somewhere along the way, but I can not figure out where and what exactly... Any help is appreciated...

2 ACCEPTED SOLUTIONS

Accepted Solutions
Highlighted
Hall of Fame Cisco Employee

Interactive commands

When I wrote the function, the syntax was:

set cmd1 "first command"

set cmd [list "send" $cmd1 "responses" [list [list "expect" {[confirm]} "reply" "y"]]

array set sendexp $cmd

cli_run_interactive [list [array get sendexp]]

View solution in original post

Highlighted
Hall of Fame Cisco Employee

Interactive commands

Yeah, I forgot a closing ']'.  Change "send" to "command".  I think the developers made that change when they imported my function.

View solution in original post

12 REPLIES 12
Highlighted
Beginner

Interactive commands

It seems to me that I have a similar issue like the one described in this thread:

https://supportforums.cisco.com/thread/2032166

Highlighted
Beginner

Interactive commands

Hi Joseph,

I think you're right, as always

I tried the script on few different IOS versions I have at my disposal, here are the results:

1. Version 12.4(15)T15

SEC_BB3#more tmpsys:/lib/tcl/cli_lib.tcl

namespace eval ::cisco::eem {

    namespace export cli_open cli_exec cli_close

    namespace export cli_write cli_read cli_read_pattern

    namespace export cli_read_line cli_read_drain

    namespace export cli_get_ttyname

So here most of the commands explained in the document I refered to are listed... but not the one I'm trying to use...

2. Version 15.2(4)M3

namespace eval ::cisco::eem {

    namespace export cli_open cli_exec cli_close

    namespace export cli_write cli_read cli_read_pattern

    namespace export cli_read_line cli_read_drain

    namespace export cli_get_ttyname

    namespace export cli_run cli_run_interactive

    namespace export xml_pi_exec xml_pi_parse xml_pi_write xml_pi_read

3. The system where I've executed the script, Version 12.4(13b)

Terminal#more tmpsys:/lib/tcl/cli_lib.tc                                      

                      ^

% Invalid input detected at '^' marker.

So I guess I definatelly need an upgrade at least to IOS version 12.4(15)T15 where I could at least use cli_read_pattern and do the same thing. I'll see what I could do tomorrow and I'll update the thread...

Are you aware of any reference document, so that I could check which is the minimum supproted IOS version?

Highlighted
Hall of Fame Cisco Employee

Interactive commands

You need at least EEM 3.0 for this function.  That would be 12.4(22)T or higher.  The cli_read_pattern function is supported in 12.4(13b) (EEM 2.1).

Highlighted
Beginner

Interactive commands

Hi Joseph,

I upgraded the system to one of the latest versions 15.1(4)M7.

Terminal#more tmpsys:/lib/tcl/cli_lib.tcl

namespace eval ::cisco::eem {

    namespace export cli_open cli_exec cli_close

    namespace export cli_write cli_read cli_read_pattern

    namespace export cli_read_line cli_read_drain

    namespace export cli_get_ttyname

    namespace export cli_run cli_run_interactive

    namespace export xml_pi_exec xml_pi_parse xml_pi_write xml_pi_read

So  this command should be implemented. And indeed it is. But than again,  when I try to execute the script, I've got a strange error....

Terminal_Training#event manager run run_interactive.tcl

list must have an even number of elements

    while executing

"array set sendexp $cmd"

    (procedure "cli_run_interactive" line 19)

    invoked from within

"cli_run_interactive { clist }"

    invoked from within

"$slave eval $Contents"

    (procedure "eval_script" line 7)

    invoked from within

"eval_script slave $scriptname"

    invoked from within

"if {$security_level == 1} {       #untrusted script

     interp create -safe slave

     interp share {} stdin slave

     interp share {} stdout slave

..."

    (file "tmpsys:/lib/tcl/base.tcl" line 50)

Tcl policy execute failed: list must have an even number of elements

The error is quite clear, but why? According to the guide

http://www.cisco.com/en/US/docs/ios-xml/ios/eem/configuration/xe-3se/5700/eem-cli-library-tcl.pdf

on page 8, I've just used the example, but with one command only:

set cmd1 "first command"

set cmd1_exp1 {[confirm]}

set cmd1_rep1 {y}

set cmd1_response [list [list expect $cmd1_exp1 reply $cmd1_rep1]]

Am I missing something?

Highlighted
Hall of Fame Cisco Employee

Interactive commands

When I wrote the function, the syntax was:

set cmd1 "first command"

set cmd [list "send" $cmd1 "responses" [list [list "expect" {[confirm]} "reply" "y"]]

array set sendexp $cmd

cli_run_interactive [list [array get sendexp]]

View solution in original post

Highlighted
Beginner

Interactive commands

Joseph,

I believe an additional square braket is needed in the line:

set cmd [list "send" $cmd1 "responses" [list [list "expect" {[confirm]} "reply" "y"]]]

Otherwise it does not let me register the policy.

I'm runnint version 15.1(4)M7 on this machine.

Terminal#more tmpsys:/lib/tcl/cli_lib.tcl

namespace eval ::cisco::eem {

    namespace export cli_open cli_exec cli_close

    namespace export cli_write cli_read cli_read_pattern

    namespace export cli_read_line cli_read_drain

    namespace export cli_get_ttyname

    namespace export cli_run cli_run_interactive

    namespace export xml_pi_exec xml_pi_parse xml_pi_write xml_pi_read

Below is the result I've got:

Terminal#event manager run run_interactive.tcl

can't read "sendexp(command)": no such element in array

    while executing

"cli_run_interactive [list [array get sendexp]]"

    invoked from within

"$slave eval $Contents"

    (procedure "eval_script" line 7)

    invoked from within

"eval_script slave $scriptname"

    invoked from within

"if {$security_level == 1} {       #untrusted script

     interp create -safe slave

     interp share {} stdin slave

     interp share {} stdout slave

..."

    (file "tmpsys:/lib/tcl/base.tcl" line 50)

Tcl policy execute failed: can't read "sendexp(command)": no such element in array

Highlighted
Hall of Fame Cisco Employee

Interactive commands

Yeah, I forgot a closing ']'.  Change "send" to "command".  I think the developers made that change when they imported my function.

View solution in original post

Highlighted
Beginner

Interactive commands

I can confirm, that changing the script... it finally works

What is the proper way of putting log messages in between the cli commands, so that I could follow the script execution and possibly finding mistakes in my logic?

I mean, this is quite a simple script... even though I've written it using wrong syntax But in a more elaborate scripts, it would be quite nice to follow log messages that are generated at certain points of the script...

I found the following in one example.. somewhere on the net:

 action_syslog priority emergencies msg "Log message"

Thank your for your persistence and promptness. I really appreciate it!

Regards,

Boyan

Highlighted
Hall of Fame Cisco Employee

Interactive commands

action_syslog is the way to go.  If the script is synchronous, then you can also use "puts" to print a string to the current terminal.

Highlighted
Beginner

Interactive commands

I also noticed that the following debug:

debug event manager tcl cli_library

Produces outputs like these, which are quite nice:

*Oct  9 17:23:41.211: %HA_EM-6-LOG: run_interactive.tcl : DEBUG(cli_lib) : CTL : cli_open called.
*Oct  9 17:23:41.383: %HA_EM-6-LOG: run_interactive.tcl : DEBUG(cli_lib) : OUT : Terminal#
*Oct  9 17:23:41.383: %HA_EM-6-LOG: run_interactive.tcl : DEBUG(cli_lib) : IN  : Terminal#enable
*Oct  9 17:23:41.503: %HA_EM-6-LOG: run_interactive.tcl : DEBUG(cli_lib) : OUT : Terminal#
*Oct  9 17:23:41.503: %HA_EM-6-LOG: run_interactive.tcl : DEBUG(cli_lib) : IN  : Terminal#clear line 46
*Oct  9 17:23:41.707: %HA_EM-6-LOG: run_interactive.tcl : DEBUG(cli_lib) : OUT : [confirm]
*Oct  9 17:23:41.707: %HA_EM-6-LOG: run_interactive.tcl : DEBUG(cli_lib) : IN  : y
*Oct  9 17:23:41.923: %HA_EM-6-LOG: run_interactive.tcl : DEBUG(cli_lib) : OUT : y [OK]
*Oct  9 17:23:41.923: %HA_EM-6-LOG: run_interactive.tcl : DEBUG(cli_lib) : OUT : Terminal#
*Oct  9 17:23:41.923: %HA_EM-6-LOG: run_interactive.tcl : DEBUG(cli_lib) : OUT : Terminal#
*Oct  9 17:23:41.923: %HA_EM-6-LOG: run_interactive.tcl : DEBUG(cli_lib) : CTL : cli_close called.

So I guess, cli_open and cli_close are implemented withing the cli_run_interactive function and are automatically called upon execution....

Highlighted
Hall of Fame Cisco Employee

Interactive commands

Yes, it has to in order to open the CLI session.  The debug is a good way to see what the commands are doing, but if you want to add your own logic, use puts or action_syslog.

Highlighted
Hall of Fame Cisco Employee

Interactive commands

You may not have the function.  What version of IOS do you have?  If you do "more tmpsys:/lib/tcl/cli_lib.tcl" do you see this proc?

CreatePlease to create content
Content for Community-Ad
July's Community Spotlight Awards