Sure...
This can be improved in many ways, but I've not had the impetus to actually do much with it. YMMV. It tries to be "safe" by dropping out if something fails, but this does mean that you will need to "manually recover" depending on where things broke.
This is a script that I run on a macOS host to backup a directly attached pool (Work) to a directly attached backup pool (Tub). Tub is also used for backing up other pools too (same host and others).
- Code: Select all
#!/bin/bash
pool="Work"
destination="Tub/Work"
prev_file="${HOME}/.backupWorkPreviousSnap"
type=work
today=$(date +"${type}-%Y-%m-%d_%H:%M:%S")
# Create today snapshot
snapshot_today="${pool}@${today}"
previous=$(cat ${prev_file})
if [ 0 -ne ${?} ]; then
# Initial run...
previous=${today}
snapshot_previous=${pool}@${previous}
echo " No previous snapshot. Creating first snapshot - \"${snapshot_previous}\"."
sudo zfs snapshot -r ${snapshot_previous}
echo " Performing first sync."
sudo sh -c "zfs send -R ${snapshot_previous} | zfs receive -Fduvs ${destination}"
if [ 0 -ne ${?} ]; then
echo " Initial backup failed. Removing snapshot ${snapshot_previous}."
sudo zfs destroy -r ${snapshot_previous}
exit 1
else
# Record new snapshot as previous backup.
echo "${previous}" > ${prev_file}
fi
exit 0
else
# Look for yesterday snapshot
snapshot_previous="${pool}@${previous}"
fi
# Look for a snapshot with today's name
if sudo zfs list -H -o name -t snapshot | sort | grep "${snapshot_today}$" > /dev/null; then
echo " Snapshot \"${snapshot_today}\" already exists. Stopping."
exit 1
else
echo " Taking todays snapshot - \"${snapshot_today}\"."
sudo zfs snapshot -r ${snapshot_today}
fi
if sudo zfs list -H -o name -t snapshot | sort | grep "${snapshot_previous}$" > /dev/null; then
echo " Previous snapshot \"${snapshot_previous}\" exists. Proceeding with backup."
sudo sh -c "zfs send -R -i ${snapshot_previous} ${snapshot_today} | zfs receive -Fduvs ${destination}"
if [ 0 -ne ${?} ]; then
echo " Backup failed. Removing snapshot ${snapshot_today}."
sudo zfs destroy -r ${snapshot_today}
exit 1
else
# Record today's snapshot as previous backup.
echo "${today}" > ${prev_file}
fi
echo " Backup complete destroying previous snapshot - \"${snapshot_previous}\"."
sudo zfs destroy -r ${snapshot_previous}
exit 0
else
echo " Missing previous snapshot ${snapshot_previous} aborting."
exit 1
fi
Something-something about no warranty expressed or implied, this script could eat your homework or kill your favorite pot plant, ... caveat emptor.
Update: This script is intended for attended execution. I should reference Lundman's point here too - without having sudo NOPASS config for the zfs command, you will need to enter your password at least once. If the send/receive takes a while, you will be prompted again at the end for your password (sudo authentication for your session timing out).
Cheers!