Resume rsync over SSH after broken connection?

48

16

I have to transfer large amounts of data (>80 GB) over ssh using rsync. Everything is working fine, but the DSL connection where the backup data is sent from will drop once every 24h for up to 3 minutes (switching providers is not an option).

How do I:

  1. Automatically restart the transfer when the connection is back up?

  2. Make sure there are not by accident two rsync commands running at the same time?

Andreas

Posted 2011-06-27T11:24:06.003

Reputation:

Possible duplicate of http://serverfault.com/q/98745.

– tanius – 2015-07-26T07:28:52.070

Some useful info here - I just want to add that one way of getting round the repeated asking for password problem is to use the 'sshpass' command. Usually this needs to be installed with apt-get etc. – Rachael Saunders – 2017-10-02T09:30:08.253

Can't you check the return code? while ./run_script; do echo "Retrying..."; done; echo "Done." Make sure run_script returns 0 on success. – Kerrek SB – 2011-06-27T11:28:20.647

Answers

56

The following should be helpful:

#!/bin/bash

while [ 1 ]
do
    rsync -avz --partial source dest
    if [ "$?" = "0" ] ; then
        echo "rsync completed normally"
        exit
    else
        echo "Rsync failure. Backing off and retrying..."
        sleep 180
    fi
done

When the connection dies, rsync will quit with a non-zero exit code. This script simply keeps re-running rsync, letting it continue until the synchronisation completes normally.

Peter

Posted 2011-06-27T11:24:06.003

Reputation: 661

1--partial only keeps partial files; you need --append to append to them. – Cees Timmerman – 2015-09-15T16:56:24.147

1You should consider using the -eq instead of =. The first compares two integers (which is correct) and the latter first converts these to strings and compares these strings. Should work here but to keep it "correct". See man (1) test. – Christian Wolf – 2016-03-17T19:20:23.757

1Thanks, I'm trying this now... but should this: if [ "$?" = "0" ] not be: if [ "$?" == "0" ] (comparision operator)? – None – 2011-06-27T12:55:24.437

1No, in bash "=" is string equality (one of the many things that makes it confusing, I think!) – Peter – 2011-06-27T15:11:10.797

6== is alias for = :D – bbaja42 – 2011-06-27T16:27:09.690

8Ah, good to know. bash will never cease to amaze/horrify me :-P – Peter – 2011-06-28T23:32:24.123

2Late to the party, however for posterity: A) just use: if rsync -avz --partial source dest; then ... B) if you want to compare integral values if use double parenthesis for arithmetic expansion: if (( $? = 0 )) then; – user18402 – 2014-03-14T04:44:43.230

8

This does much the same as Peter's answer, but gives the user the option of which remote file he wants, and where he wants to save it (as well as conducting the rsync over ssh). Replace the USER and HOST with your username and host respectively.

#!/bin/bash
echo -e "Please enter the full (escaped) file path:"
read -r path
echo "Path: $path"
echo -e "Enter the destination:"
read -r dst
echo "Destination: $dst"
while [ 1 ]
do
    rsync --progress --partial --append -vz -e ssh "USER@HOST:$path" $dst
    if [ "$?" = "0" ] ; then
        echo "rsync completed normally"
        exit
    else
        echo "rsync failure. Retrying in a minute..."
        sleep 60
    fi
done

The rsync options used here enable the progress stats during transfer, the saving of partial files upon unexpected failure, and the ability to append to partially completed files upon resume. The -v option increases verbosity, the -z option enables compression (good for a slow connection, but requires more cpu power on both ends), and the -e option enables us to conduct this transfer over ssh (encryption is always good).

Note: Use this only if you have public key login enabled with your ssh, otherwise it will ask you for a password when it restarts (killing all functionality of the script).

KernelSanders

Posted 2011-06-27T11:24:06.003

Reputation: 836

1

This is the best answer of the original question. It also applies to a duplicate with the wrong answer at: http://serverfault.com/questions/98745/how-to-repeatedly-call-rsync-until-files-are-sucessfully-transferred

– rickfoosusa – 2016-01-23T19:15:23.807

5

supervisor daemon (a process control manager) could work very well after creating rsa certificates of both sides, with a similar configuration as follows: (/etc/supervisor/ supervisord.conf is the configuration file path on debian based systems )

[program:rsync-remoteserver]
command=rsync -avz --progress root@server.com:/destination /backup-path
stdout_logfile=/out-log-path  
stderr_logfile=/errlogpath

ugurarpaci

Posted 2011-06-27T11:24:06.003

Reputation: 51

1

The @Peter's answer seems be very useful, but for me it was important to use --update option. After connection has been resumed, without --update rsync was trying to sync all from the very begining. With --update, files that already exists are skipped.

rsync --partial --update --progress -r [SOURCE] [DESTINATION]

YasiuMaster

Posted 2011-06-27T11:24:06.003

Reputation: 31

2--update skips files that already exists... Including those that have not been completely copied to the target. I think it goes against most use cases. – durum – 2017-11-22T17:20:19.397

@durum it's not true at least on rsync 3.1.2 . after interrupted transfer I see it works properly on the same file. I used rsync over ssh, the command was rsync --partial --update file1 remotehost:file1. after transferring 15% I broke the transfer (kill -KILL). – filiprem – 2019-01-17T10:24:16.333