user1902689
user1902689

Reputation: 1775

expect script bug with expect timeout, exp_continue, or multiple expect possibilities

I'd like for an expect script to start a ssh session, automatically answer "yes" if asked if you're sure, then at the password prompt, temporarily pass interaction to the user for them to enter their password, then to take it back after detecting the user hit enter. Oh, and to continually retry if there's a 3 second timeout, in case the ssh server on fileServer isn't up yet.

 1: expect "root*archiso*# "
 2: puts "\n<<< Make sure sshd is started on fileServer >>>\n"
 3: set readyForPassword 0
 4: while { $readyForPassword == 0 } {
 5:    send "scp guest@fileServer:/public/* /publicCopy\n"
 6:    expect -timeout 3 {
 7:       "Are you sure you want to continue connecting (yes/no)? " {
 8:          send "yes\n"
 9:          exp_continue
10:       } "password: " {
11:          set readyForPassword 1
12:       }
13:    }
14: }
15: interact "\n" return
16: send "\n"

What I think the code is going to do follows. Line 6 will look for a match on "Are you sure you want to continue connecting (yes/no)? " or "password: ". If it times out after 3 seconds, the while loop will restart, and scp will be tried again. If it matches the former line, it will send "yes\n" and look for an additional 3 seconds for "password: ". If it matches "password: " either the first time, or after sending "yes", it will exit the while loop.

Line 15 will let the user type in the password, and when enter is pressed, control will return back to the expect script. The user's enter doesn't get sent, so send an enter in its place.

My understanding is clearly off. sshd is started on fileServer, so it immediately gets to the password prompt. If I do nothing, in 3 seconds, it hits enter for me. Then it hits enter about once per second, until the third failure, when scp aborts. Then, it tries scp again, repeating the process forever. So, clearly, readyForPassword is never getting set to 1.

This type of while / readyForPassword loop works in other locations in my code, so it's something to do with timeout, exp_continue, or handling multiple possibilities for expect - those are the new things to me in this section of code.

I'm wondering if after "yes\n" is sent, when that triggers "password: " to be sent, if exp_continue isn't re-evaluating the new text including "password: ". But, if that's the case, I'm not sure how to fix it.

Also, I think it's not just hitting enter for the password for me, I'm pretty sure it's send the scp line as the password.

Upvotes: 0

Views: 1758

Answers (1)

Dinesh
Dinesh

Reputation: 16428

You should use carriage-return \r to match user's 'enter' key input, not the line-feed \n character. Change it as,

 interact "\r" return
 send \r
 expect "root*archiso*# "

Also, it is recommended to use \r always, instead of \n.

Upvotes: 1

Related Questions