My Bash script for waking my Mac in the middle of the night and triggering a Kopia Snapshot

I wanted to share the Bash script that I created, thanks to u/kapitainsky and other sources online.

I have a folder on my Mac that I need backed up at least daily so I found the best way to do that (at least for me) using Kopia. Here are a few things that it does:

  1. Triggers early in the morning (wakes Mac from sleep and Kopia takes the snapshot)
  2. Checks for Internet connection
  3. Downloads current iCloud files from iCloud to ensure up-to-date folder
  4. Completes Kopia Snapshot
  5. Dialogue Boxes that will pop up if an error occurs w/ the error message displayed
  6. A log that tracks success, failures, errors in a local file

It works well and does everything I need it to.

First you have to set your Mac to automatically wake up at a time during the night. Use this to do that:

sudo pmset repeat wake MTWRFSU 04:00:00 # Wake at 4:00am

Then you can run this on a set schedule at that same time. I used Automator on my Mac to do this. It comes preinstalled on Mac and is pretty easy to use.

#!/bin/bash
# Prevent sleep until this script is finished
/usr/bin/caffeinate -i -w $$ &

# Confirm the log directory exists (not the file)
log_dir=$(dirname "YOUR_PATH")

# Create the directory if it doesn't exist
mkdir -p "$log_dir"

# Log file location
log_file="YOUR_PATH"

# Verbose logging setting (set to 1 for detailed logs, 0 for normal logging)
VERBOSE=0

# Function to log messages
log_message() {
    # Log the message to the log file
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$log_file"
    # If VERBOSE is set to 1, print it to the terminal as well
    if [ $VERBOSE -eq 1 ]; then
        echo "$(date '+%Y-%m-%d %H:%M:%S') - $1"
    fi
}

# Log that the script is starting
log_message "------- SCRIPT STARTED -------"

# Function to display a macOS dialog box
show_error_dialog() {
    osascript -e "display dialog \"$1\" buttons {\"OK\"} with icon caution"
    log_message "Error: $1"
}

# Function to check for internet connection
check_internet() {
    log_message "Checking internet connection..."
    if ping -q -c 1 -W 1 8.8.8.8 > /dev/null; then
        log_message "Internet is available."
        return 0
    else
        log_message "No internet connection. Skipping operations."
        return 1
    fi
}

# Check for internet connection
if ! check_internet; then
    show_error_dialog "No internet connection detected. Operations have been skipped."
    exit 0 # Exit script if no internet connection
fi

# Download iCloud folder
log_message "Starting download of iCloud folder..."
cd ~"YOUR_PATH"
download_output=$(find . -type f -print0 | xargs -0 brctl download 2>&1)

if [ $? -eq 0 ]; then
    log_message "Download iCloud folder completed successfully."
    echo "Download iCloud folder completed successfully!"
else
    log_message "Download iCloud folder failed. Error: $download_output"
    osascript -e "display dialog \"Download iCloud folder failed. Please check logs or internet connection. Error: $download_output\" buttons {\"OK\"} with icon caution"
    exit 1
fi

# Run Kopia snapshot create with error checking
log_message "Running Kopia snapshot creation..."
create_output=$(/Applications/KopiaUI.app/Contents/Resources/server/kopia snapshot create --all 2>&1)
if [ $? -ne 0 ]; then
    log_message "Kopia snapshot creation failed. Error: $create_output"
    show_error_dialog "Kopia snapshot creation failed. Please check the logs or configuration. Error: $create_output"
    exit 1
else
    # Verbose output for the create command (only if VERBOSE is enabled)
    if [ $VERBOSE -eq 1 ]; then
        log_message "Kopia snapshot create command output: $create_output"
    fi
fi

# Run Kopia maintenance with error checking
log_message "Running Kopia maintenance..."
maintenance_output=$(/Applications/KopiaUI.app/Contents/Resources/server/kopia maintenance run --full 2>&1)
if [ $? -ne 0 ]; then
    log_message "Kopia maintenance failed. Error: $maintenance_output"
    show_error_dialog "Kopia maintenance failed. Please check the logs or configuration. Error: $maintenance_output"
    exit 1
else
    # Verbose output for the maintenance command (only if VERBOSE is enabled)
    if [ $VERBOSE -eq 1 ]; then
        log_message "Kopia maintenance command output: $maintenance_output"
    fi
fi

# Run Kopia snapshot verify with error checking
log_message "Running Kopia snapshot verification..."
verify_output=$(/Applications/KopiaUI.app/Contents/Resources/server/kopia snapshot verify --verify-files-percent=3 2>&1)
if [ $? -ne 0 ]; then
    log_message "Kopia snapshot verification failed. Error: $verify_output"
    show_error_dialog "Kopia snapshot verification failed. Please check the logs or configuration. Error: $verify_output"
    exit 1
else
    # Verbose output for the verify command (only if VERBOSE is enabled)
    if [ $VERBOSE -eq 1 ]; then
        log_message "Kopia snapshot verify command output: $verify_output"
    fi
fi

# If all Kopia commands succeed
log_message "All Kopia operations completed successfully!"
echo "All Kopia operations completed successfully!"

# Wait for 3 seconds before sleeping
log_message "Waiting for 3 seconds before putting the system to sleep..."
sleep 3

# Put Mac to sleep now that snapshot is completed and verified
log_message "Putting the Mac to sleep..."
pmset sleepnow

# Exit script
exit

You obviously need to enter your own pathways anywhere I entered “YOUR_PATH”. Otherwise it should be fairly plug and play assuming you have KopiaUI installed. I’m not the best coder and this was the first time I ever used Bash, so you may want to tweak a few things. But I did testing and it all seems to work. There could be differences in our machines though so ymmv

Good luck!