Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I was hoping to get a little insight into an expect script that I've written.

Basically we have this expect script to perform an sftp upload, key authentication is not an option, and sftp is the only method supported by our vendor, thus the need for this.

I want to be able to catch timeouts and log an error code for scripting purposes.

I need to:

  • Log into sftp site
  • Begin Transfer
  • Detect that upload has hit 100%
  • If upload does not hit 100% within a certain time, I want to log an error code for scripting purposes.

Here is what I have so far:

set timeout 10
spawn sftp
match_max 100000
expect "password: "
send -- "PASSWORD\n"
expect "sftp> "
send -- "lcd /data/upload\n"
expect "sftp> "
send -- "put file_yyyymmdd\n"
expect "*100%*" {send "quit\n" } \
timeout { exit 2 }
expect "sftp> "
send -- "quit\n"
expect eof

I believe the code is working up to the timeout, below is the log from the expect session:

spawn sftp's password: 
Connected to
sftp> lcd /data/upload/
sftp> put file_yyyymmdd
Uploading file_yyyymmdd to /home/user/file_yyyymmdd
file_yyyymmdd                                 0%    0     0.0KB/s   --:-- ETA
file_yyyymmdd                               100% 5835     5.7KB/s   00:00    
sftp> quit

It appears the "quit" is sent twice? Which I guess makes sense b/c it sees the 100% and immediately sends the "quit" before the prompt is ready.

What changes should I make to get my expected results?

Any help would be much appreciated.

On another note, I'd like to expand this expect script, or create another that detects when the DES key has changed, accept it (send yes), and continue.

However I would like to know when this happens, either with an error code, or writing something to a log file...

I've tried the following but it is not working as expected:

set timeout 10
spawn sftp
match_max 100000
expect "Are you sure you want to continue connecting (yes/no)? " {send "yes\r" } \\
timeout { exit 0 }
sleep 2
exit 3
expect eof

The thought was to use the exit codes to determine if the key had to be updated, however it always comes back as exit code 3 (key changed) and didn't send a "yes" when the key actually did change.

Again any help would be greatly appreciated.

share|improve this question
You should send \r not \n -- \r corresponds to the user hitting enter. – glenn jackman Feb 27 '12 at 19:54

For the timeout:

expect "*100%*" {send "quit\n" } \
timeout { exit 2 }
expect "sftp> "
send -- "quit\n"
expect eof

should be changed to (formatted differently for clarity as well)

expect {
  "*100%*" { } 
  timeout { exit 2 }
expect "sftp> "
send -- "quit\n"
expect eof

The "*100%*" { } section tells it to exit the expect statement and move onto the next line:

expect "sftp> "

The DES key change expect may need to have the parenthesis escaped. Try setting exp_internal 1 in your script to see better debugging messages. It may not be matching correctly.

edit: It could be the space at the end as well.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.