Updated 2010-05-05 08:34:44 by dkf
exp_continue ?-continue_timer?

The standard documentation appears for this under-appreciated command in the Expect extension here [1].

exp_continue isn't strictly necessary. One could write a loop from other, more primitive, elements. However, exp_continue is a great convenience for the common situation where it can be used to easily implement various client/server models in expect, such as FTP, SMTP or HTTP (but see [2]), where we are uncertain about the number and order of commands sent by server. [explain much more]

exp_continue is labeled as "under-appreciated" above because there's such a gap between the large number of people who can program basic exp_send-expect sequences, and the small minority who are familiar with exp_continue, despite the latter's usefulness.

Don Libes is quoted at http://coding.derkeiler.com/Archive/Tcl/comp.lang.tcl/2004-07/0437.html as saying "As far as the difference between while and exp_continue, it's mostly a matter of style. The exp_continue is also faster but it's imperceptible in most real-world applications."

[provide sample code for some client/server]

An example that uses exp_continue ( check if a user/password combination is valid ):
 proc auth_user { user pass } {
        global spawn_id
        set success 0
        log_user 0
        spawn ssh -l $user localhost
        set spid $spawn_id

        expect -i $spid \
                  "word: "      {
                                exp_send -i $spid "${pass}\r"
                                if { $success == 0 } {
                                        incr success -1
                                        exp_continue
                                }
                } "> "  {
                        exp_send -i $spid "exit\r"
                        set success 1
                } "continue connecting (yes/no)? "      {
                        exp_send -i $spid "yes\r"
                        exp_continue
                } "incorrect"   {
                        set success -4
                        exp_send -i $spid "\r"
                } "try again."  {
                        set success -4
                        exp_send -i $spid "\r"
                } timeout       {
                        set success -1
                }

        exp_close -i $spid
        exp_wait
        puts stderr authuser:$success
        return [ expr ( $success == 1 ) ? 1 : 0 ]
 }

[Category Command|Category Expect]

[spaceBAR] - 2010-03-01 17:56:21

<FYI, Another example for the exp_continue that I came up with while doing some SCP testing/research and it will fit nicely with the statement [explain much more] ~:) -
# Set named parameters
set scp_cmd "scp user@host:/filename or filename(s) pattern /tmp"
set scp_pass "password"
set timeout 120

# Procedure to scp file from server
proc scpfile { scp_pass } {
  expect {
    # Send password at 'Password' prompt and tell expect to continue(i.e. exp_continue)
    # processing responses staying in this 'expect' block.
    # 'exp_continue' avoids having to write a another expect statement( think of it kinda like a loop, I said kinda )
    -re "\[P|p]assword:" { exp_send "$scp_pass\r"
                           exp_continue  }
    # Tell expect stay in this 'expect' block and for each character that SCP prints while doing the copy
    # reset the timeout counter back to 0.
    -re .                { exp_continue  }
    timeout              { return 1      }
    eof                  { return 0      }
  }
}

# Execute SCP command
eval spawn $scp_cmd
set scpfile_results [scpfile $scp_pass]

# If successful SCP, ...
if { $scpfile_results == 0 } {
  # Successful SCP session so exit with zero status
  exit 0
}

# Error attempting SCP, so exit with non-zero status
exit 1

>