Here I show you how to repeat a command until it finishes successfully. This should only be done with programs that support resume and also have legit exit codes (or else they might run on for forever – read on). I show how I constructed such a function, by first showing how to create a function that repeats rsync only. Then we build a function that can repeat anything.

Sometimes you will run a command and it will fail. However you can repeat that same command to resume it where it left off. A good example is “rsync”. rsync can be made to resume from where it left off – I use the partial option (-P gives progress bar and partial option at the same time). This can be done with any command that supports resume and has good exit codes (meaning success is 0, and fails are none 0).

Two criteria for this to work

  1. supports resume in a good way (cp supports resume, but its not good – see below, rsync supports good resume)
  2. has good exit codes (0 is success, none-zero for none-success)

Note that “cp” is not a good example of a command that can resume where it left off (even if you use -u), because it will skip the files that where partially copied. So if you have 10 big files, and the “cp” got cut off mid 5th file, when you repeat the command, it will just continue with the 6th file. The 5th file will be incomplete.

We will use a recursive method to do this repeating resume operation.

RRSYNC – Repeating Rsync

First I will show how to do this with rsync. We basically run rsync, then if its exit code is zero we exit out, if its exit code is none zero we repeat the function.

Check the comments for how to run it. Basically you would first copy paste that function into a shell and then run this  rrsync 1 -avhP <src> <dest> . Also if you had the above code in a script file. Such as rrsync.sh. You would need to source the script first to get that function to be available in the shell source rrsync.sh  or the shorthand way . rrsync.sh

Note I decided to keep track of a variable (so that I can show which run number this is), and the only way to do that within a recursive function is with global variables, or a variable that you pass on to the next level. Since I didnt want to use global variables, I just passed it on to the next level, the caveat is that we have to specify the start value of this variable when we begin (hence the 1 before the arguments)

REPEAT function

The next code allows me to repeat any function. I didnt want the user to worry about having to provide 1 all the time, so I created a starting function called “repeat”, which calls the code that does everything “repeatrecurse”.

So copy&  paste the above two functions into a shell to source them (or source them thru a script with the source  bash builtin), so that you can use repeat. Then to utilize the repeat function do this:

Rsync will then repeat until success.

You can test the code by creating two small functions one which always returns success (exit code 0, so it will only run once), and one that will always return none-success (none-zero exit code, so it will run forever until someone presses Control-C or kills it)

You can test them like so

Here we show how it runs once when we have a successful end

Here we show how it repeats

The end

 

Leave a Reply

Your email address will not be published. Required fields are marked *