Romuald
Romuald

Reputation: 11

Command not write in buffer with Expect

I try to backup a Linkproof device with expect script and i have some trouble. It's my first script in expect and i have reach my limits ;)

#!/usr/bin/expect
spawn ssh @IPADDRESS
expect "username:"
# Send the username, and then wait for a password prompt.
send "@username\r"
expect "password:"
# Send the password, and then wait for a shell prompt.
send "@password\r"
expect "#"
# Send the prebuilt command, and then wait for another shell prompt.
send "system config immediate\r"
#Send space to pass the pause
expect -re "^ *--More--\[^\n\r]*"
send ""
expect -re "^ *--More--\[^\n\r]*"
send ""
expect -re "^ *--More--\[^\n\r]*"
send ""
# Capture the results of the command into a variable. This can be displayed, or written to disk.
sleep 10
expect -re .*
set results $expect_out(buffer)
# Copy buffer in a file
set config [open linkproof.txt w]
puts $config $results
close $config
# Exit the session.
expect "#"
send "logout\r"
expect eof

The content of the output file:

The authenticity of host '@IP (XXX.XXX.XXX.XXX)' can't be established.

RSA key fingerprint is XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.

Are you sure you want to continue connecting (yes/no)? @username

Please type 'yes' or 'no': @password

Please type 'yes' or 'no': system config immediate

Please type 'yes' or 'no':


Like you can see, the result of the command is not in the file. Could you, please, help me to understantd why ? Thanks for your help.

Romuald

Upvotes: 1

Views: 2023

Answers (2)

Xarses
Xarses

Reputation: 315

As @joefis mentioned, you do need to catch the yes/no from ssh.

I've copied this from my response in serverexchange as its highly relevant here

You will want to avoid using "Password:" if you monitor your strings during login, you will find that it is not always capitalized.

Changing your expect to -re "(.*)assword:" or "assword:" tends to be much more effective for catching the line.

If you find that the timings are still too quick you can put a sleep 1; before your send

This is what i use for expect

expect {
    #When asked about authenticity, answer yes then restart expect block
    "(yes/no)?" { 
        send "yes\n"
        exp_continue 
    }
    "passphrase" { send "\r" }
    -re "(.*)assword:"  { sleep 1; send -- "password\r" }
    -re $prompt { return }
    timeout     { puts "un-able to login: timeout\n"; return }
    eof         { puts "Closed\n" ; return }
}

so a couple of things, this will allow for expect to respond to any of these results on a single expect, it will then only continue to more of the code if a return statement is found. I would recommend setting a prompt value as it becomes help full to detect if your commands are complete or your login was indeed successful.

Upvotes: 1

eemz
eemz

Reputation: 1211

All of your "expect" statements are timing out because the text they are waiting for does not match the text that actually appears. Let's examine the first one or two, the others are all the same.

You say:

expect "username:"

But what it actually receives from ssh is:

The authenticity of host '@IP (XXX.XXX.XXX.XXX)' can't be established.
RSA key fingerprint is XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.
Are you sure you want to continue connecting (yes/no)?

This does not contain the string "username:" so the expect command will time out, and the script will move on to the next command:

send "@username\r"

We can see it does send that:

Are you sure you want to continue connecting (yes/no)? @username

But that's not a valid answer to this question.

And the rest of the output is the same idea over and over.

Upvotes: 3

Related Questions