3
\$\begingroup\$

I have not been able to find a good implementation of using rsync to do daily, weekly and monthly backups with hard links anywhere. So I wrote my own and I am now looking for critique before I set it live on an unRAID production server. Anything I should fix?

#!/bin/bash
#
# Daily/Weekly/Monthly Backup
#
PROG_NAME=DailyWeeklyMonthlyBackup
BACKUPPOINT=/mnt/user
MOUNTPOINT=/mnt/disks/REDBackup
DAYOFWEEK_NAME=$(date +"%a")
DAYOFWEEK_NUMERAL_WEEKLY=$(date +"%u")
DAYOFWEEK_NUMERAL_MONTHLY=$(date +"%d")

logger Started -t$PROG_NAME $(date "+%m-%d-%Y %r")

if [ -d $MOUNTPOINT ]
then

    # Daily Backup START
    ############################
    rsync -a -v --delete $BACKUPPOINT/ $MOUNTPOINT/Daily/ 2>&1
    logger Daily REDBackup Completed -t$PROG_NAME $(date "+%m-%d-%Y %r")
    /usr/local/emhttp/webGui/scripts/notify -e "unRAID Server Notice" -s "Server Backup" -d "Daily REDBackup completed" -i "normal"

    # Weekly Sunday Backup START
    ############################
    if [ $DAYOFWEEK_NUMERAL_WEEKLY == 7 ]
    then
        rsync -avH --delete --link-dest=$MOUNTPOINT/Daily/ $BACKUPPOINT/ $MOUNTPOINT/Weekly/ 2>&1
        logger Weekly REDBackup Completed -t$PROG_NAME $(date "+%m-%d-%Y %r")
        /usr/local/emhttp/webGui/scripts/notify -e "unRAID Server Notice" -s "Server Backup" -d "Weekly REDBackup completed" -i "normal"
    fi

    # Monthly Backup START
    ############################
    if [ $DAYOFWEEK_NUMERAL_MONTHLY == 1 ]
    then
        rsync -avH --delete --link-dest=$MOUNTPOINT/Daily/ $BACKUPPOINT/ $MOUNTPOINT/Monthly/ 2>&1
        logger Monthly REDBackup Completed -t$PROG_NAME $(date "+%m-%d-%Y %r")
        /usr/local/emhttp/webGui/scripts/notify -e "unRAID Server Notice" -s "Server Backup" -d "Monthly REDBackup completed" -i "normal"
    fi

else

    logger REDBackup Drive Not Mounted -t$PROG_NAME $(date "+%m-%d-%Y %r")
    /usr/local/emhttp/webGui/scripts/notify -e "unRAID Server Notice" -s "Server Backup" -d "Daily REDBackup failed" -i "alert"

fi
\$\endgroup\$
  • 2
    \$\begingroup\$ Heh, for what it is worth, have a look at my implementation on a similar system here: codereview.stackexchange.com/questions/41928/… \$\endgroup\$ – rolfl Mar 7 '18 at 0:56
  • \$\begingroup\$ (Welcome to CR!) To separate things that are common from those different between controlled blocks, factor out what is common - simplifies not only modification, but review, too. (notify: /usr/local/emhttp/webGui/scripts/notify -e "unRAID Server Notice" -s "Server Backup", sync: rsync -av --delete $SYNCFLAGS $BACKUPPOINT/ $MOUNTPOINT/$MOUNTSUB/ 2>&1…) What about rsync exit code? \$\endgroup\$ – greybeard Mar 7 '18 at 5:10
  • \$\begingroup\$ @greybeard your comment belongs in an answer ;-) \$\endgroup\$ – janos Mar 7 '18 at 18:49
1
\$\begingroup\$

Error handling

Error handling is always important, especially when working with something so important as backups. In particular, the result of the rsync commands is not checked, the script logs "backup completed" messages, which doesn't say anything about success or failure.

I suggest to add a check on the exit status of all the rsync commands, and to make the log message reflect the state of success/failure (or simply include the exit code directly).

Don't repeat yourself

There are some repeating elements in the code:

  • logger $period REDBackup $result -t$PROG_NAME $(date "+%m-%d-%Y %r")
  • /usr/local/emhttp/webGui/scripts/notify -e "unRAID Server Notice" -s "Server Backup" -d "$period REDBackup $result" -i "normal"

I replaced with $period and $result the parts that could be parameterized. Extracting these commands to helper functions can greatly reduce duplicated logic, and improve readability.

A word on quoting

It's recommended to double-quote all variables used as command arguments. For example instead of this:

rsync -a -v --delete $BACKUPPOINT/ $MOUNTPOINT/Daily/ 2>&1

It will be safer to write:

rsync -a -v --delete "$BACKUPPOINT"/ "$MOUNTPOINT"/Daily/ 2>&1

Maybe you know that these variables will always be safe. But it's good to take this simple precaution anyway, and make it a habit so it's automatic and you will never fall in a trap of unintended word splitting or globbing.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.