Expect Script Error Handling

Good Day Everyone,

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 user@xxx.xxx.xxx.xxx
  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 user@xxx.xxx.xxx.xxx
  user@xxx.xxx.xxx.xxx's password: 
  Connected to xxx.xxx.xxx.xxx.
  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    
  quit
  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 user@xxx.xxx.xxx.xxx
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.

Thanks,

If you used sftp with keys, you wouldn't need to install or use a third-party brute-forcing utility to forcefeed plaintext passwords into ssh in an insecure manner for you. "interactive password authentication" means "password typed by a human being in realtime authentication" and nothing else will do. It's so difficult for a reason -- ssh is designed to prevent it, because it's almost impossible to keep unencoded passwords secure, and because allowing them would be just the avenue hackers need to bruteforce your own system or use your system as a platform to bruteforce others.

Google 'passwordless ssh' to find the proper way to do this with keys, there's hundreds of tutorials all over the internet.

I realize this, and do this with some of our other scripts, however as I mentioned this sftp site is hosted by a third party and ssh keys are not an option.

I'm not even questioning how to send the password, log in, etc... My question is about error handling with expect. The other parts of the script are already working.

I'm interested in expects ability to see a prompt and send certain text back as a response, and when a prompt is received that is different than what is expected how to handle that.