Hourly macOS Network Backup Using rsync and launchd (macOS 10.11 El Capitan)

Overview

This procedure creates an automated hourly backup that:

  • Copies files from a source folder to a mounted network share.
  • Does not delete or modify the source files.
  • Runs automatically every hour using launchd.
  • Displays a Notification Center alert only when a backup fails.
  • Logs failures to a text file.
  • Can easily be reconfigured for different client locations by changing the destination volume name.

Step 1: Identify the Source Folder

Open Terminal and navigate to the folder you want to back up.

cd ~/Documents
pwd

Example output:

/Users/dean/Documents

Suppose the folder you want to copy is:

/Users/dean/Documents/CaseFiles

Record this path.


Step 2: Determine the Destination Volume Name

Mount the network share.

In Finder:

Go → Connect to Server

Example:

smb://Office-Mac

After connecting, determine the mounted volume name:

ls /Volumes

Example output:

Macintosh HD
OfficeBackup

The mounted volume name is:

OfficeBackup

Record this name.


Step 3: Create a Scripts Folder

Create a folder to store the backup script.

mkdir -p ~/Scripts

Verify:

ls -ld ~/Scripts

Step 4: Create the Backup Script

Create the script file:

nano ~/Scripts/hourly_backup.sh

Paste the following script:

#!/bin/bash

SOURCE="/Users/dean/Documents/CaseFiles"
DEST="/Volumes/OfficeBackup"

if [ ! -d "$DEST" ]; then

    /usr/bin/osascript <<EOF
display notification "Destination volume is not mounted." with title "Backup Error"
EOF

    exit 1
fi

/usr/bin/rsync -av --ignore-existing "$SOURCE/" "$DEST/"
RESULT=$?

if [ $RESULT -ne 0 ]; then

    case $RESULT in
        3) ERROR="Source or destination unavailable" ;;
        10) ERROR="Network communication error" ;;
        11) ERROR="File I/O error" ;;
        12) ERROR="Transfer protocol error" ;;
        20) ERROR="Transfer interrupted" ;;
        23) ERROR="Partial transfer due to file access problem" ;;
        24) ERROR="Source file changed during transfer" ;;
        30) ERROR="Network timeout" ;;
        *) ERROR="Unknown rsync error (code $RESULT)" ;;
    esac

    /usr/bin/osascript <<EOF
display notification "$ERROR" with title "Backup Error ($RESULT)"
EOF

    echo "$(date): $ERROR" >> "$HOME/backup.log"
fi

Save and exit:

Control-O
Return
Control-X

Step 5: Make the Script Executable

chmod +x ~/Scripts/hourly_backup.sh

Verify:

ls -l ~/Scripts/hourly_backup.sh

You should see executable permissions:

-rwxr-xr-x

Step 6: Test the Script Manually

Run the script:

~/Scripts/hourly_backup.sh

If the destination is mounted and files copy successfully, the script is functioning correctly.


Step 7: Test Failure Notifications

Temporarily edit the script:

nano ~/Scripts/hourly_backup.sh

Change:

DEST="/Volumes/OfficeBackup"

to:

DEST="/Volumes/DoesNotExist"

Run:

~/Scripts/hourly_backup.sh

You should receive a Notification Center alert indicating that the destination volume is not mounted.

Restore the correct destination afterward.


Step 8: Create the LaunchAgents Folder

mkdir -p ~/Library/LaunchAgents

Step 9: Create the LaunchAgent Configuration

Create the LaunchAgent file:

nano ~/Library/LaunchAgents/com.dean.hourlybackup.plist

Paste:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">

<plist version="1.0">
<dict>

    <key>Label</key>
    <string>com.dean.hourlybackup</string>

    <key>ProgramArguments</key>
    <array>
        <string>/Users/dean/Scripts/hourly_backup.sh</string>
    </array>

    <key>RunAtLoad</key>
    <true/>

    <key>StartInterval</key>
    <integer>3600</integer>

</dict>
</plist>

Replace dean with the actual username on the Mac.

Save and exit.


Step 10: Load the LaunchAgent

Load the job:

launchctl load ~/Library/LaunchAgents/com.dean.hourlybackup.plist

Verify that it is loaded:

launchctl list | grep hourlybackup

Expected output:

com.dean.hourlybackup

Step 11: Trigger an Immediate Test Run

Instead of waiting an hour:

launchctl start com.dean.hourlybackup

The script should execute immediately.


Changing Locations (Lab vs Client Site)

The only value that should need changing is the destination volume.

Determine the mounted volume name:

ls /Volumes

Example:

Macintosh HD
LabBackup

Edit the script:

nano ~/Scripts/hourly_backup.sh

Change:

DEST="/Volumes/OfficeBackup"

to:

DEST="/Volumes/LabBackup"

Save and exit.

No LaunchAgent changes are required.

The next scheduled run will automatically use the new destination.


Reloading the LaunchAgent

You only need to reload the LaunchAgent if the .plist file changes.

Unload:

launchctl unload ~/Library/LaunchAgents/com.dean.hourlybackup.plist

Reload:

launchctl load ~/Library/LaunchAgents/com.dean.hourlybackup.plist

Useful Commands

View Recent Errors

tail -20 ~/backup.log

Check Mounted Volumes

ls /Volumes

Run the Script Manually

~/Scripts/hourly_backup.sh

Verify LaunchAgent Status

launchctl list | grep hourlybackup

Notes

  • The source files are never deleted.
  • Existing files on the destination are not overwritten because --ignore-existing is used.
  • A Notification Center alert appears only when an error occurs.
  • Failed transfers are logged to ~/backup.log.
  • The destination network share must be mounted before the backup runs.
  • The Mac must be logged in for Notification Center alerts to appear.

Leave a Comment

Scroll to Top