Cisco Support Community
cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Community Member

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
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]]

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.

12 REPLIES
Community Member

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

Community Member

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?

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).

Community Member

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?

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]]

Community Member

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

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.

Community Member

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

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.

Community Member

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....

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.

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?

956
Views
0
Helpful
12
Replies
CreatePlease to create content