How to continue rsync on disconnects?
Rsync is a great software, I have been using it for decades to transfer files from different servers. However one issue with it, is if you were to get any network disconnects, it would be nice to have a way to restart rsync automatically on any errors.
To accomplish this, we can write a shell script to catch any rsync errors in a loop, and restart it only on errors. Perfect!
To start let’s do the following:
alias pico='nano -w' cd pico rsync_restart.sh
Now we have our file open let us copy and paste this following script inside the file. I have 2 examples here, first one commented out I use with no bandwidth limits, second one I use to place a bandwidth limit of 30 Megabytes so I do not overload poor gigabit connection. Replace the uncommented rsync line with your rsync line, do not forget the ending semi colon to finish.
#!/bin/bash #keep rsync going! #Run in screen session - "screen -S rsync" #Ctrl-a-d to disconnect, screen -r rsync(to re-attach) export Result=1; while [ $Result -ne 0 ]; do echo "STARTING ($Result) @" `date`; echo "Started On `date`" >> rsync.log #PUT YOUR SYNC COMMAND HERE: #rsync -Wal4vv --progress --partial --timeout=10 --bwlimit=0 --delete --force 192.168.0.3::data /data; rsync -Wal4vv --progress --partial --timeout=10 --bwlimit=30M --delete --force 192.168.0.3::data /data; Result=$?; sleep 1; done
Once you pasted that in, exit with Ctrl-x and save the file.
If you are running –delete in your rsync command, do not run this program in that directory or you will erase this program and our rsync.log tracker file!
Let’s take a look at what this script is doing(for those interested in what program is actually doing). First thing it starts a bash script with our she-bang line. We then remove any rsync.log we might have had, so we know how many times rsync restarted for only this session. Next we export a starting variable “Result” and assign that to 1. Now we start a while loop that will loop infinitely with our rsync command until such time as Result is not equal to 0. So it first goes into the while loop because Result is not 0, it is 1. Next we display to screen(STDOUT) we are starting along with date, and put everytime rsync starts in a file called rsync.log so we can check how many time rsync restarted time to time. Now we execute our rsync command. After rsync command exits, bash stores exit code of a program in a special variable called “$?”, which is always an integer, normally 0 or 1, and assign that to variable Result. If rsync fails in anyway, Result would be set to “0”. In programming 0 means false, and 1 means true. If rsync completes successfully, Result will equal to 1 and break the while loop because Result will no longer not equal 0. Our next line “sleep 1”, is simply good practice to not let cpu run at 100% in an infinite loop if something ever went wrong by letting it pause for a moment while in an infinite loop. So if rsync completes successfully it will exit while loop and program in this case, otherwise it will start over with first echo lines in the while loop till it is successful.
Alright next thing we want to do is run the script:
chmod 755 rsync_restart.sh screen -S rsync ./rsync_restart.sh ctrl-a-d (disconnect from screen session)
Great now we are off to the races! Hit “Ctrl-a-d” to disconnect screen and if you have terrabytes of data to transfer, just check in occasionally on transfer.
cd tail -100 rsync.log screen -r rsync
Until next time, happy transferring.
Dan.