You are not logged in.

#1 2012-11-03 01:38:26

jynnantonix
Member
Registered: 2012-09-07
Posts: 33

Time Machine-like collection of backup scripts

I use OS X on my laptop and I wanted to have a backup utility similar to Time Machine for my Arch workstation.  Inspired by Mike Rubel's rsync snapshot script [1], I wrote three scripts that keep hourly incremental snapshots for the past day, daily snapshots for the past week, and weekly snapshots beyond that point.  This an example layout of the backups directory

|---{backup_dir}
      |---hourly
           |---20121104203106
                |---/boot
                |---/bin
                |---and the rest
           |---20121104212257
      |---daily
           |---20121103223155
      |---weekly
           |---20121024081234
      |---current@  -->  {backup_dir}/hourly/20121104203106

current is a soft link to the latest snapshot directory, and the scripts assume it already exists i.e., you've already made a backup with rsync.  I didn't make a script for this since it's a one-liner that you are only going to run once anyway. 

Anyway, this goes in cron.hourly

#!/bin/bash
#
# @file       snapshot
# @author     Chirantan Ekbote (chirantan.ekbote <at> gmail.com)
# @date       2012-10-18
# @version    0.3
# @brief      Script to generate a snapshot of the system using rsync.
#
# ----------------------------------------------------------------------

unset PATH  # suggestion from H. Milz: avoid accidental use of $PATH

# ------------- system commands used by this script --------------------

MOUNT=/bin/mount;

ECHO=/usr/bin/echo;
RM=/usr/bin/rm;
LN=/usr/bin/ln;
MKDIR=/usr/bin/mkdir;
RSYNC=/usr/bin/rsync;
DATE=/usr/bin/date;

# ------------- file locations -----------------------------------------

SOURCE_DIR=/;
BACKUP_DEV=/dev/md3;
BACKUP_DIR=/mnt/backups;
EXCLUDES=/home/lost+found,/dev/*,/proc/*,/var/lib/pacman/sync/*,\
/home/*/.thumbnails/*,/sys/*,/tmp/*,/run/*,/mnt/*,/media/*,/lost+found,\
/home/*/.gvfs;
EXCLUDE_ARGS=`eval ${ECHO} --exclude={"${EXCLUDES}"}`;

# ------------- the script itself --------------------------------------

# Get the current time. We will use this as the name of the backup folder
TIME=$($DATE +%Y%m%d%H%M%S) ;

# mount the snapshot mountpoint as read-write
$MOUNT -o remount,rw "${BACKUP_DEV}" "${BACKUP_DIR}" ;
if (( $? )); then
{
    $ECHO "snapshot: could not remount ${BACKUP_DIR} readwrite";
    exit;
}
fi;

# Make the backup directory
$MKDIR "${BACKUP_DIR}"/hourly/$TIME;

# Do the backup
$RSYNC -aAX --link-dest="${BACKUP_DIR}"/current/ $EXCLUDE_ARGS \
"${SOURCE_DIR}"/* "${BACKUP_DIR}"/hourly/$TIME ;

# update the current backup
$RM "${BACKUP_DIR}"/current ;
$LN -s "${BACKUP_DIR}"/hourly/$TIME "${BACKUP_DIR}"/current ;

# now remount the RW snapshot mountpoint as readonly
$MOUNT -o remount,ro "${BACKUP_DEV}" "${BACKUP_DIR}" ;
if (( $? )); then
{
    $ECHO "snapshot: could not remount ${BACKUP_DIR} readonly";
    exit;
} fi;

This one in cron.daily

#!/bin/bash
#
# @file       daily-snapshot
# @author     Chirantan Ekbote (chirantan.ekbote <at> gmail.com)
# @date       2012-11-01
# @version    0.3
# @brief      Script to consolidate all snapshots older than 24 hours
#             into one daily snapshot
#
# ----------------------------------------------------------------------

unset PATH  # suggestion from H. Milz: avoid accidental use of $PATH

# ------------- system commands used by this script --------------------

MOUNT=/bin/mount;

ECHO=/usr/bin/echo;
MV=/usr/bin/mv;
RM=/usr/bin/rm;
SORT=/usr/bin/sort;
FIND=/usr/bin/find;

# ------------- file locations -----------------------------------------

BACKUP_DEV=/dev/md3;
BACKUP_DIR=/mnt/backups;

# ------------- the script itself --------------------------------------

# mount the snapshot mounpoint as read-write
$MOUNT -o remount,rw "${BACKUP_DEV}" "${BACKUP_DIR}" ;
if (( $? )); then
{
    $ECHO "snapshot: could not remount ${BACKUP_DIR} readwrite";
    exit;
}
fi;

# Get all the snapshots more than 24 hours old
OLD_SNAPSHOTS=(`${SORT} -r <( ${FIND} "${BACKUP_DIR}"/hourly/ -maxdepth \
1 -mtime +1) `);

# Move the latest snapshot to the daily directory
$MV "${OLD_SNAPSHOTS[0]}" "${BACKUP_DIR}"/daily ;

# Delete all the other snapshots
$RM -r "${OLD_SNAPSHOTS[@]:1}" ;

# now remount the RW snapshot mountpoint as readonly
$MOUNT -o remount,ro "${BACKUP_DEV}" "${BACKUP_DIR}" ;
if (( $? )); then
{
    $ECHO "snapshot: could not remount ${BACKUP_DIR} readonly";
    exit;
} fi;

And this one in cron.weekly

#!/bin/bash
#
# @file       weekly-snapshot
# @author     Chirantan Ekbote (chirantan.ekbote <at> gmail.com)
# @date       2012-11-01
# @version    0.3
# @brief      Script to consolidate all snapshots older than 7 days
#             into one weekly snapshot
#
# ----------------------------------------------------------------------

unset PATH  # suggestion from H. Milz: avoid accidental use of $PATH

# ------------- system commands used by this script --------------------

MOUNT=/bin/mount;

ECHO=/usr/bin/echo;
MV=/usr/bin/mv;
RM=/usr/bin/rm;
SORT=/usr/bin/sort;
FIND=/usr/bin/find;

# ------------- file locations -----------------------------------------

BACKUP_DEV=/dev/md3;
BACKUP_DIR=/mnt/backups;

# ------------- the script itself --------------------------------------

# mount the snapshot mounpoint as read-write
$MOUNT -o remount,rw "${BACKUP_DEV}" "${BACKUP_DIR}" ;
if (( $? )); then
{
    $ECHO "snapshot: could not remount ${BACKUP_DIR} readwrite";
    exit;
}
fi;

# Get all the snapshots more than 7 days old
OLD_SNAPSHOTS=(`${SORT} -r <( ${FIND} "${BACKUP_DIR}"/daily/ -maxdepth \
1 -mtime +7) `);

# Move the latest snapshot to the weekly directory
$MV "${OLD_SNAPSHOTS[0]}" "${BACKUP_DIR}"/weekly ;

# Delete all the other snapshots
$RM -r "${OLD_SNAPSHOTS[@]:1}" ;

# now remount the RW snapshot mountpoint as readonly
$MOUNT -o remount,ro "${BACKUP_DEV}" "${BACKUP_DIR}" ;
if (( $? )); then
{
    $ECHO "snapshot: could not remount ${BACKUP_DIR} readonly";
    exit;
} fi;

I'm pretty new to bash so any suggestions/criticisms would be helpful.


[1] http://www.mikerubel.org/computers/rsync_snapshots/

Offline

Board footer

Powered by FluxBB