Training, Open Source computer languages
PerlPHPPythonMySQLApache / TomcatTclRubyJavaC and C++LinuxCSS 
Search for:
Home Accessibility Courses Diary The Mouth Forum Resources Site Map About Us Contact
 
For 2023 (and 2024 ...) - we are now fully retired from IT training.
We have made many, many friends over 25 years of teaching about Python, Tcl, Perl, PHP, Lua, Java, C and C++ - and MySQL, Linux and Solaris/SunOS too. Our training notes are now very much out of date, but due to upward compatability most of our examples remain operational and even relevant ad you are welcome to make us if them "as seen" and at your own risk.

Lisa and I (Graham) now live in what was our training centre in Melksham - happy to meet with former delegates here - but do check ahead before coming round. We are far from inactive - rather, enjoying the times that we are retired but still healthy enough in mind and body to be active!

I am also active in many other area and still look after a lot of web sites - you can find an index ((here))
Unable to interact from within a proc

Posted by doublea1535 (doublea1535), 22 August 2006
I am having trouble with my script executing 'interact' the way I want it to. I am defining a proc admindown, then calling it later in the script. Within the proc, I want to prompt the user to choose an answer. The trouble I am having is that I am defining interact but when I run the script it is not interacting (waiting for user input).

Does something special need to be done in order to interact from within a proc? I will add the necessary pattern handlers later, but right now I can't even get it to wait on the user. (note I added a timeout statement in case that was an issue, but it did not help)

Code example:
---
proc admindown {} {
       puts "\nNotice: Interface is adminsitratively down"
       puts -nonewline "This interface will need to be administratively enabled "
       puts "for either testing or service"
       puts "----------------------------------"
       set timeout 30
       puts "Would you like to admin up the interface?"
       puts "yes\/no \[yes\]?"
       interact
}
admindown
---

Here is what I see when I run it (it never pauses or waits for input):
---
Notice: Interface is adminsitratively down
This interface will need to be administratively enabled for either testing or service
----------------------------------
Would you like to admin up the interface?
yes/no [yes]?
exit
Connection to aggr01.den01 closed.
---


Posted by admin (Graham Ellis), 23 August 2006
I suspect  the problem's in the process that you've spawned ... which isn't included in your sample code.   Run stand-alone, you code gives me the message:

cannot interact with self - set spawn_id to a spawned process

Is your spawned process something that read from STDIN?

Posted by doublea1535 (doublea1535), 23 August 2006
Here is the complete script:

#!/usr/local/bin/expect
;# name: t1test
;# desc: check status, check/put/drop loop, perform line testing

;# sanity check
set scrip [exec echo $argv0 | sed -e {s/.*\///}]
set d -
set usage "$scrip hostname${d}interface{\[slot/\]mod/port\[:channel\]}"
set examp "$scrip aggr01.den01${d}Serial1/0/21:0"
set err "$usage\n$examp"
if { "$argv" == "" } { puts $usage; exit 1 }

;# define variables
exec echo $argv
set host [exec echo $argv | sed -e {s/-.*//}]
set int [exec echo $argv | sed -e {s/.*-//}]
set intst ""
set logfile /tmp/$scrip.tmp
log_file -a -noappend $logfile
set user $env(USER)


;# error messages
set interr "\nFor some reason, the interface name was not picked up, sending to interact\n"

;# sanity check
if { "" == "$host" } { puts $err; exit 1
       } elseif {
"" == "$int" } { puts $err; exit 1 }

;# define procedures

proc login {} {
       log_user 1
       interact -o # return
       log_user 0
}

proc getstatus {} {
       global int; global host; global d; global int; global intst; global interr
       send "show interface $int\n"
       expect -re "${int} is" { send "exit\n" } "#" { puts $interr; interact -o exit }
}

proc noshut {} {
       puts adminup
}

proc admindown {} {
       puts "\nNotice: Interface is adminsitratively down"
       puts -nonewline "This interface will need to be administratively enabled "
       puts "for either testing or service"
       puts "----------------------------------"
       set timeout 30
       puts "Would you like to admin up the interface?"
       puts "yes\/no \[yes\]?"
       interact
}

proc intdown {} {
       t1test
}

proc intup {} {
       puts "This circuit is currently up.\n"
       puts "DS1 lins testing IS intrusive and will disrupt service.\n"
       puts "Do you wish to procede with testing?\n"
       puts "yes/no \[yes\]?"
       interact -o "\r" { t1test } \
               "yes" { t1test } \
               "no" { return } \
}


;# begin script
;# log into agg router
spawn ssh $user@$host
expect "assword:" { login } "authenticity" { send "yes\n"; login }

;# fetch interface status info
getstatus

;# parse status info
set intline [exec cat $logfile | grep "$int is"]
set l1stat [exec echo $intline | sed -e {s/,.*//} -e {s/.*is //}]
set l2stat [exec echo $intline | sed -e {s/.*, //}]

;#
puts "\n\nInterface $int Status\n---------------"
puts "Layer 1 status: $l1stat"
puts "Layer 2 status: $l2stat"

if { "$l1stat" == "administratively down" } {
       admindown
       } elseif { "$l1stat" == "down" } {
       t1test
       } elseif { "$l1stat" == "up" } {
       intup
}


>  Is your spawned process something that read from STDIN?

I am not sure exactly what you're referring to as the spawned process. Do you mean the expect script, the interact that I am calling from within the proc, or the procedure admindown ? I want the interact statement to read from STDIN (user input) and they will need to select yes or no to the question about whether or not to perform the loop test.

Posted by admin (Graham Ellis), 23 August 2006
on 08/23/06 at 02:08:23, doublea1535 wrote:
Here is the complete script:

[snip]

I am not sure exactly what you're referring to as the spawned process. Do you mean the expect script, the interact that I am calling from within the proc, or the procedure admindown ? I want the interact statement to read from STDIN (user input) and they will need to select yes or no to the question about whether or not to perform the loop test.


I mean the process that you started up with the spawn command ... which I now see is an ssh.  What I was looking for in my previous post was a few extra lines to show how that was set up / what you are interacting with.

It's hard to see from your whole program which is why our FAQ asks you to cut the problem down to a maximum of 30 lines. Can I suggest that your next step might be to come up with a complete (non) working example of the problem within that limit ... if the program still fails and, after experimenting with it, you can't see why then post here as a follow up by all means.   But I rather suspect you'll be able to find the problem by yourself using this technique, whichI've persoanlly found to solve most of my own problems.   If that's the case, please follow up to let me and other readers know what the answer was.

Thanks.

Posted by doublea1535 (doublea1535), 23 August 2006
Here is my script (26 lines) :

---
#!/usr/local/bin/expect
set host [exec echo $argv | sed -e {s/-.*//}]
set int [exec echo $argv | sed -e {s/.*-//}]
proc login {} {
       log_user 1
       interact -o # return
}
proc getstatus {} {
       global int
       send "show interface $int\n"
       expect -re "${int} is" { send "exit\n" } "#" { puts error; interact -o exit }
}
proc admindown {} {
       puts "\nNotice: Interface is adminsitratively down"
       puts -nonewline "This interface will need to be administratively enabled "
       puts "for either testing or service"
       puts "----------------------------------"
       puts "Would you like to admin up the interface?"
       puts "yes\/no \[yes\]?"
       interact
}
spawn ssh user@$host
expect "assword:" { login } "authenticity" { send "yes\n"; login }
getstatus
admindown
---

When I run it I get this:

---
user@server ~/bin/expect : t1test2 aggr01.den01-Serial4/0:1
spawn ssh user@aggr01.den01
user@aggr01.den01's password:
Signon successful.
aggr01.den01
Notice: Interface is adminsitratively down
This interface will need to be administratively enabled for either testing or service
----------------------------------
Would you like to admin up the interface?
yes/no [yes]?
exit
---

It's like it's skipping past the interact statement.

Posted by doublea1535 (doublea1535), 23 August 2006
Graham, you were right  

I trimmed it down to 26 lines, then was reviewing it one last time before submitting it and noticed that I had exited from my "spawn ssh" in a previous proc.

Posted by admin (Graham Ellis), 23 August 2006
Glad it's sorted - thanks for the feedback

--Graham



This page is a thread posted to the opentalk forum at www.opentalk.org.uk and archived here for reference. To jump to the archive index please follow this link.

You can Add a comment or ranking to this page

© WELL HOUSE CONSULTANTS LTD., 2024: Well House Manor • 48 Spa Road • Melksham, Wiltshire • United Kingdom • SN12 7NY
PH: 01144 1225 708225 • FAX: 01144 1225 793803 • EMAIL: info@wellho.net • WEB: http://www.wellho.net • SKYPE: wellho