I ran into this same problem a while back. In the end I wrote something similar to David's answer, but gussied it up a little with max retries, responding to Ctrl-C, and such: http://blog.iangreenleaf.com/2009/03/rsync-and-retrying-until-we-get-it.html.
The obvious solution is to check the return value, and if rsync returns anything but success, run it again. Here was my first try:
while [ $? -ne 0 ]; do rsync -avz --progress --partial /rsync/source/folder ba[email protected]:/rsync/destination/folder; done
The problem with this is that if you want to halt the program, Ctrl-C only stops the current rsync process, and the loop helpfully starts another one immediately. Even worse, my connection kept breaking so hard that rsync would quit with the same "unkown" error code on connection problems as it did on a SIGINT, so I couldn't have my loop differentiate and break when needed. Here is my final script:
#!/bin/bash
### ABOUT
### Runs rsync, retrying on errors up to a maximum number of tries.
### Simply edit the rsync line in the script to whatever parameters you need.
# Trap interrupts and exit instead of continuing the loop
trap "echo Exited!; exit;" SIGINT SIGTERM
MAX_RETRIES=50
i=0
# Set the initial return value to failure
false
while [ $? -ne 0 -a $i -lt $MAX_RETRIES ]
do
i=$(($i+1))
rsync -avz --progress --partial /rsync/source/folder [email protected]:/rsync/destination/folder
done
if [ $i -eq $MAX_RETRIES ]
then
echo "Hit maximum number of retries, giving up."
fi