From: tom on
Hello,

Armed with Exploring Expect and Google I have been working on a script
to automate some testing. As a part of this testing I need to reboot a
router, but I have been having a tough time getting the router to
actually reboot without the expect script going sideways. Here is the
snippet of code giving me trouble:

spawn telnet 50.50.50.26 2323
expect "Login:"
send "root\r\n"
expect "Password:"
send "password\r\n"
expect "Go to the previous menu"
send "r"
expect "Continue to restart?\r\ny/n:"
send "y"
expect "System is being restarted...\r\n"
## The router doesn't close the telnet connection when it reboots,
exit telnet manually
## Pull up the telnet prompt
send "\x1d"
expect "\r\ntelnet> "
## Quit Telnet
send "quit\r"
#expect "Connection closed.\r\n"
## Expect eof, this should signal when telnet terminates, right?
expect eof

## Prompt for permission to continue.
set timeout -1
puts "\nPPP\nPPP Type y to continue\nPPP\n"
expect {
timeout {puts "\nEEE\nEEE Timeout. This should never happen,
but at least it's a script error. Die.\nEEE\n"; exit}
"y" {return}
eof {puts "Caught EOF!"}
}
exit

My expectation is that expect logs into the router, sends the
necessary keystrokes to reboot it, exits, then prompts for
confirmation before continuing. The relevant output I get when I run
the script is..

expect: does "\r\n\r\n\r\nContinue to restart?\r\ny/n: " (spawn_id
exp6) match glob pattern "Continue to restart?\r\ny/n:"? yes
expect: set expect_out(0,string) "Continue to restart?\r\ny/n:"
expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) "\r\n\r\n\r\nContinue to restart?\r\ny/
n:"
send: sending "y" to { exp6 }

expect: does " " (spawn_id exp6) match glob pattern "System is being
restarted...\r\n"? no


expect: does " \r\n" (spawn_id exp6) match glob pattern "System is
being restarted...\r\n"? no
System is being restarted...

expect: does " \r\nSystem is being restarted...\r\n" (spawn_id exp6)
match glob pattern "System is being restarted...\r\n"? yes
expect: set expect_out(0,string) "System is being restarted...\r\n"
expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) " \r\nSystem is being restarted...\r\n"
send: sending "\u001d" to { exp6 }

expect: does "" (spawn_id exp6) match glob pattern "telnet>"? no

telnet>
expect: does "\r\ntelnet> " (spawn_id exp6) match glob pattern
"telnet>"? yes
expect: set expect_out(0,string) "telnet>"
expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) "\r\ntelnet>"
send: sending "quit\r" to { exp6 }
quit
Connection closed.
expect: read eof
expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) " quit\r\nConnection closed.\r\n"
write() failed to write anything - will sleep(1) and retry...

PPP
PPP Type y to continue
PPP

expect: spawn id exp6 not open
while executing
"expect -nobrace timeout {puts "\nEEE\nEEE Timeout. This should never
happen, but at least it's a script error. Die.\nEEE\n"; exit} y return
eof {puts ..."
invoked from within
"expect {
timeout {puts "\nEEE\nEEE Timeout. This should never happen, but at
least it's a script error. Die.\nEEE\n"; exit}
"y" {return}
eof {puts ..."
(file "dnsobs.exp" line 305)

I suspect that the problem has to do with telnet not closing tidily,
or expect not realizing that it has closed. So far I have been unable
to figure out a workable solution. Any help would be appreciated.
Thanks.
From: Bruce Hartweg on
tom wrote:
> Hello,
>
> Armed with Exploring Expect and Google I have been working on a script
> to automate some testing. As a part of this testing I need to reboot a
> router, but I have been having a tough time getting the router to
> actually reboot without the expect script going sideways. Here is the
> snippet of code giving me trouble:
>
> spawn telnet 50.50.50.26 2323
> expect "Login:"
> send "root\r\n"
> expect "Password:"
> send "password\r\n"
> expect "Go to the previous menu"
> send "r"
> expect "Continue to restart?\r\ny/n:"
> send "y"
> expect "System is being restarted...\r\n"
> ## The router doesn't close the telnet connection when it reboots,
> exit telnet manually
> ## Pull up the telnet prompt
> send "\x1d"
> expect "\r\ntelnet> "
> ## Quit Telnet
> send "quit\r"
> #expect "Connection closed.\r\n"
> ## Expect eof, this should signal when telnet terminates, right?
> expect eof
>
^^^^^^^^^^^^
this "expect eof" is the final interaction with your spawned
telnet session - so nothing further is needed

> ## Prompt for permission to continue.
> set timeout -1
> puts "\nPPP\nPPP Type y to continue\nPPP\n"

this next expect is now trying to talk to your old (now defunct)
spawn_id which is why you get the error, you need to be using
expect_user to interact with the user at the keyboard.

> expect {
> timeout {puts "\nEEE\nEEE Timeout. This should never happen,
> but at least it's a script error. Die.\nEEE\n"; exit}
> "y" {return}
> eof {puts "Caught EOF!"}
> }
> exit
>


Hope it helps,
Bruce
From: tom on
Works perfectly, I knew it had to be something silly I was missing.
Thanks a million!

>
> Hope it helps,
>    Bruce