2

My goal is to rename a file on an sftp server using expect, AND if the rename fails, to exit expect returning a status code of 1

My expect script works fine - it successfully renames.

I cannot work out how to exit with a status code if the rename fails.

ubuntu@ip-10-0-0-138:~$> cat expect_script.txt
spawn sftp -o "StrictHostKeyChecking no" ubuntu@nginx.localvpc
expect "password:"
send "somesupersecretpassword\n"
expect "sftp>"
send "rename /var/www/static/tmp-93121715.mp4  /var/www/static/91329728.mp4\n"
expect "sftp>"
send "rename /var/www/static/91329728.mp4  /var/www/static/tmp-93121715.mp4\n"
expect "sftp>"
send "bye\n"
expect "#"
exit

Here is the output when I run my script:

ubuntu@ip-10-0-0-138:~$> expect -f expect_script.txt
spawn sftp -o StrictHostKeyChecking no ubuntu@nginx.localvpc
ubuntu@nginx.localvpc's password:
Connected to nginx.localvpc.
sftp> rename /var/www/static/tmp-93121715.mp4  /var/www/static/91329728.mp4
rename /var/www/static/tmp-93121715.mp4  /var/www/static/91329728.mp4
sftp> rename /var/www/static/91329728.mp4  /var/www/static/tmp-93121715.mp4
rename /var/www/static/91329728.mp4  /var/www/static/tmp-93121715.mp4
sftp> bye
bye
ubuntu@ip-10-0-0-138:~$>

Can anyone please suggest what I can do to exit with return code zero if the rename fails?

Bonus question... what's the correct way to exit at the end of my expect script? Is it one of these?

exit
close
expect eof

thanks!

  • not sure if u have to use Expect but take a look at sexpect with which you can write Expect scripts with shell code only. – pynexj Aug 27 '18 at 8:25
2

You need to check for a rename failure by matching that text and acting on it. This can be abstracted into a proc (what TCL calls a subroutine or function).

spawn ...
set ret 0
expect "sftp>"
proc sftp_rename {from to} {
    global ret
    send "rename $from $to\n"
    expect {
        -ex "Couldn't" { set ret 42; exp_continue }
        "sftp>"
    }
}
sftp_rename /var/www/static/tmp-93121715.mp4 /var/www/static/91329728.mp4
sftp_rename /var/www/static/91329728.mp4 /var/www/static/tmp-93121715.mp4
send "bye\n"
expect eof
exit $ret

I would use expect eof as I would expect the sftp connection to go away at that point.

1

My man page for expect says:

exit [-opts] [status]

[...] status (or 0 if not specified) is returned as the exit status of Expect.

So you simply want exit 1.


As for your three alternatives, expect eof would wait for the command expect is talking with to reach EOF. You might continue the expect script after that. expect eof is useful in cases where that's just one of the options, or when the remote might detect the disconnection and take it as an error. (Of course if both sides of the conversation wait for the other to stop, then they're stuck.)

close would close the connection to the other process, so in sense acting as the reverse of expect eof. Again, your script could continue after this. Using close just before exiting the script doesn't do much, as an exit will also implicitly close.

Then there's exit that exits your script. Choosing between the three depends on what you want to do. If you want to exit, I'd say just exit, and let the remote deal with the EOF.

  • Thanks @ilkkachu but how do I make it exit if the expected text does not come back? – Duke Dougal Aug 23 '18 at 0:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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