Epicserve

Backup files from your Mac computer to a Network Windows Share

November 4, 2009 | 3:34 p.m. CST

I have just spent a considerable amount of time trying to perfect and find a backup solution to backup my files from my MacBook Pro to several different Windows Shares (SMB/CIFS). I know there are hacks out there to make time machine work with Windows Shares, but I didn’t want to mess with making the hacks work and limiting the time machine image size. After searching for free and not so free software that would have a nice GUI interface I decided to go about backing up my files the old fashioned way and writing my own Bash Shell script using rsync.

I’ve been using rysnc for years to backup web servers to other various servers, but really haven’t used it that much for backing my local desktop. After spending way to much time working on my rysnc script, I think I’ve finally come up with a solution that meets all of my requirements. Eventually I’ll probably set the script up so it runs automatically at a certain time everyday.

To use the script save the following to files on your Mac computer. I suggest saving them in a folder called “backup” under a “scripts” folder that is under your home directory (Example: /Users/username/scripts/backup).

I named the following script backup-data-to-files.sh, but you can name your file whatever you want. Just make sure you make your file executable by running this command, “chmod 744 backup-data-to-files.sh” from the OSX terminal in the same directory as your backup script file.

#!/usr/bin/env bash

# Script Settings
REMOTE_COMPUTER="files"
MNT_POINT="/Volumes/users"
MNT_STR="//brent oconnor@$REMOTE_COMPUTER/users"
SOURCE_DIR="/Users/oconnor"
TARGET_DIR="$MNT_POINT/Brent OConnor/Backup/macbook-pro"
EXCLUDE_FROM_LIST="`pwd`/backup-data-to-files-exclude-list.txt"

# This function mounts a network share
mount_dir() {
    mkdir "$MNT_POINT"
    mount_smbfs "$MNT_STR" "$MNT_POINT"
}

# Loop through the command line options
while getopts ":s" opt; do
    case $opt in
        s)
        TEST=" -n -v"
        ;;
        *)
        # Should not occur
        echo "Unknown error while processing options"
        ;;
    esac
done


# Check if the remote computer is available, if it isn't then do nothing
ping -c 1 -t 1 "$REMOTE_COMPUTER" > /dev/null 2> /dev/null # ping and discard output
if [ $? -eq 0 ]; then  # check the exit code

    # Mount the $TARGET_DIR if it's not already mounted
    if [ ! -d "$TARGET_DIR" ]; then
        mount_dir
    fi

    # If the $EXCLUDE_FROM_LIST setting isn't empty then add it to the rsync command
    if [ -n "$EXCLUDE_FROM_LIST" ]; then
        EXCLUDE_CMD=" --exclude-from $EXCLUDE_FROM_LIST"
    fi

    # The final rsync script. I had to use eval to fix an issue I was having with a space in the $TARGET_DIR
    eval rsync$TEST --delete -a"$EXCLUDE_CMD" "$SOURCE_DIR" "$'TARGET_DIR'"

fi

Next create an exclude file that will tell rsync exactly which files you want to backup. I named my exclude file backup-data-to-files-exclude-list.txt, but you can name yours whatever you want. The +<SPACE> tells rsync that you want to include the directory. You’ll see that I have directories twice with the second line having, ** at the end of the line. I basically copied that from another example I found which said this was needed to sync all of sub-directories. The -<SPACE> tells rsync the line is a file or directory that you don’t want to sync.

+ oconnor/Sites
+ oconnor/Sites/**
+ oconnor/Desktop
+ oconnor/Desktop/**
+ oconnor/Dropbox
+ oconnor/Dropbox/**
+ oconnor/code
+ oconnor/code/**
+ oconnor/scripts
+ oconnor/scripts/**
+ oconnor/Documents
+ oconnor/Documents/**
- oconnor/*

Running the script

To run the script all you have to do is go to the directory where where you saved the script in your OSX terminal and then run the script by typing ./backup-data-to-files.sh and then hitting the enter key. I recommend running the script with the -s option first so you can see what the script is going to do before you go ahead and run the command for real. Rsync calls this a dry run, I used the -s option because most other command line scripts use -s for a safe run. Using this option first is helpful in debugging and making sure your exclude file is working correctly.

I hope my script is able to save others from the time it took me to put this script together. If you like the script then feel free to buy me a song or something on my amazon wish list! :)

Comments are closed.

Comments have been close for this post.