Link to home
Start Free TrialLog in
Avatar of mlnpscda
mlnpscda

asked on

expect: timeout for pattern action block only?

Is there a way to set a timeout for just a pattern action block independent of (or maybe subordinate to) the global timeout parameter?

set timeout 15

spawn telnet $target

send "\r"
expect {
      "login:"      { send "$AUTOUSER\r" ; exp_continue }
      "ssword:"        { send "$PASSWORD\r"; exp_continue }
      "$->"            { grab_stats }
      timeout            { send_log -- "GARBAGE OR CANNOT CONNECT\n"; exit }  ## Can the  timeout for this default be set up less than the global timeout set above?
      }


Avatar of Duncan Roe
Duncan Roe
Flag of Australia image

Yes ... effectively. There is only one timeout variable, but you can change it around a block - that's quite a common thing to do
set saved_timeout $timeout
set timeout 100 ;# Or whatever you want
# Do your block here
set timeout $saved_timeout

Open in new window

Avatar of mlnpscda
mlnpscda

ASKER

So, something like:

set timeout 15

spawn telnet $target

send "\r"

set timeout 5
expect {
      "login:"      { send "$AUTOUSER\r" ; exp_continue }
      "ssword:"        { send "$PASSWORD\r"; exp_continue }
      "$->"            { grab_stats }
      default          { send_log -- "GARBAGE OR CANNOT CONNECT\n"; exit }
      }

set timeout 15
ASKER CERTIFIED SOLUTION
Avatar of Duncan Roe
Duncan Roe
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
this is good.  I'm learning something.  Thanks.

A new question comes to mind, is the 'global timeout' for the whole expect script?  In other words, the whole script has, say, 15 seconds to finish?  or just for expect blocks?

Regarding the procedure in the expect loop, let be be sure I'm understanding the keywords:

exp_continue: continue checking (looping?) inside the expect loop.
{} : exit the expect block and continue with the statements after the expect block (in this case the grab_stats statements)
exit:  exit the whole script and return to the calling shell or program (with a return code of zero or true?)

Can I do an exit <some number> to return exit codes to the calling shell or program?

Thanks again!

Your understanding is correct. Yes you can give exit a return code. exit is actually a Tcl command; the man pages for Tcl commands are in section n so you can read about Tcl's exit by entering "man -s n exit" or "man n exit". timeout is a global variable but there is a -timeout option to the expect command to set the timeout for that expect without disturbing the global.

Actually if you set timeout before reading it, you now have a local copy. See this extract from the Expect man page:

"Expect takes a rather liberal view of scoping.  In particular, variables read by commands specific to the Expect program will be sought first from the local scope,
 and  if  not  found,  in  the global  scope.   For  example, this obviates the need to place "global timeout" in every procedure you write that uses expect.  On the other
hand, variables written are always in the local scope (unless a "global" command has been issued).  The most common problem this causes is when spawn is
executed in a procedure.  Outside the procedure, spawn_id no  longer  exists,  so  the  spawned process is no longer accessible simply because of scoping.  Add a
"global spawn_id" to such a procedure."
Thanks!