Search code examples
linuxsftpexpectnassynology

SFTP Manual command succeed but script is failing at 1 or 2%


I wrote a script to transfer a folder from VPS to Synology NAS Server. The script fails at 1 or 2% transfer without any indication why. When I run the command manually it works fine without any issues and it transfer the folder flawlessly. I'm not sure what is causing this and would appreciate if i can get some guidance on where to look.

SCRIPT:

#!/usr/bin/expect
set dir [timestamp -format "%Y-%m-%d"]
spawn sftp user@host.mybackup.me
expect "Password:"
send "passw0rd\n"
expect "sftp>"
send "cd /directory/\n"
expect "sftp>"
send "put -r /home/backup/$dir\n"
expect "sftp>"
send "bye\n"

RESULT:

root@host [/scripts]# ./sftp.sh
spawn sftp user@host.synology.me
user@host.mybackup.me's password:
Connected to host.mybackup.me
sftp> cd /directory/for/backup
sftp> put -r /home/backup/2017-12-26
Uploading /home/backup/2017-12-26/ to /backup/2017-12-26
Entering /home/backup/2017-12-26/
Entering /home/backup/2017-12-26/accounts
/home/backup/2017-12-26/file1.tar.gz       2%   26MB   1.8MB/s   08:41 ETAroot@host [/scripts]#
root@host [/scripts]#

MANUAL COMMAND:

root@host [/scripts]# sftp user@host.synology.me
backup@host.mybackup.me's password:
Connected to host.mybackup.me.
sftp> cd directory
sftp> put -r /home/backup/2017-12-26
Uploading /home/backup/2017-12-26/ to /backups/2017-12-26
Entering /home/backup/2017-12-26/
Entering /home/backup/2017-12-26/accounts
/home/backup/2017-12-26/file.tar.gz             100%  959MB 820.2KB/s   19:57
/home/backup/2017-12-26/file2.tar.gz            100%  147MB   1.4MB/s   01:45
sftp> bye
root@host [/Scripts]# 

Solution

  • I guess, in your case, timeout happened with respect to Expect, since the file transfer takes some extra time than the default timeout (10seconds). You can either set the timeout to -1 or you can increase it to some higher value and the they are in the units of seconds.

    set timeout -1; # Infinite amount of waiting time
    

    or

    set timeout 300; # 5 minutes of waiting time
    

    You can keep the above statement in your code.

    send "put -r /home/backup/$dir\n"
    expect {
        timeout {puts "timeout happened"}
        "sftp>"
    }
    send "bye\r"
    expect eof
    

    Always use \r character to send 'Enter' key instead of \n. The last statement expect eof will wait for the graceful closure of sftp program.