check if storage is available and if it is execute a backup routine with passwordphrase
Steps 1, 2 and 4 are relatively straightforward and can be performed using launchd (or cron) to call a script.

My solution involves some setup, taken from this blog post:

Open Keychain Access (⌘Space Keychain Access), click on Password, then + to create a new password. User restic for the Keychain Item Name and for the Account Name. Enter the password you intend to use in the Password field (i.e. enter the same password you used when you ran restic init). Finally, click Add to complete the set-up process.


launchd (or cron) job runs every 24 hours and simply calls a shell script restic-backup.sh
restic-backup.sh checks if /Volumes/usb-storage-name is mounted, and halts if it isn't. If the drive is mounted it then checks for the existence of the /Users/user/data directory, and halts if the directory doesn't exist (it can't backup a non-existent directory!) If the backup volume is mounted and the source directory exists it then moves on to step 3...
If the environment variable RESTIC_PASSWORD is set Restic will use its value instead of prompting for a password. restic-backup.sh will set RESTIC_PASSWORD using the security command and some ruby magic:

RESTIC_PASSWORD=$(security 2&gt;&amp;1 &gt;/dev/null find-generic-password -ga restic |ruby -e 'print $1 if STDIN.gets =~ /^password: "(.*)"$/')


With RESTIC_PASSWORD set the script can now execute the backup:

restic -r /Volumes/usb-storage-name/restic-backups backup /Users/user/data

The launchd/cron job from step 1 should run every 24 hours, covering step 4 as well.


restic-backup.sh:

#!/bin/bash

# USER CONFIGURATION:    
resticuser=restic
srcdir=/Users/user/data
backupvolume=/Volumes/usb-storage-name
backupdir=${backupvolume}/restic-backups

# Script vars:
longname=$0
shortname=$(/usr/bin/basename "${longname}")

printf '%s %s (%s) running...\n' "$(date -u "+%Y-%m-%d %H:%M:%S")" "${shortname}" "${longname}"

if [[ ! -d "${srcdir}" ]]; then
    printf '%s %s does NOT exist.' "$(date -u "+%Y-%m-%d %H:%M:%S")" "${srcdir}" &gt;&amp;2
    exit 1
else
    if [[ $(mount | grep "${backupvolume}") ]]; then
        # See: http://blog.macromates.com/2006/keychain-access-from-shell/
        # Parse output of 'security' and set RESTIC_PASSWORD:
        export RESTIC_PASSWORD=$(security 2&gt;&amp;1 &gt;/dev/null find-generic-password -ga ${resticuser} |ruby -e 'print $1 if STDIN.gets =~ /^password: "(.*)"$/')
        # Run backup, capturing output in case of error:
        output=$(restic -r ${backupdir} backup "${srcdir}")
        error=$?
        if [[ "${error}" == "0" ]]; then
            printf '%s Restic backup completed successfully.\n' "$(date -u "+%Y-%m-%d %H:%M:%S")"
        else
            printf '%s Restic backup failed: error code: %s, error: %s\n' \
                    "$(date -u "+%Y-%m-%d %H:%M:%S")" "${error}" "${output}" &gt;&amp;2
        fi
    else
        printf '%s %s is NOT mounted.' "$(date -u "+%Y-%m-%d %H:%M:%S")" "${backupvolume}" &gt;&amp;2
        exit 1
    fi
fi

printf '%s %s ended.\n' "$(date -u "+%Y-%m-%d %H:%M:%S")" "${shortname}"