Skip to content

Instantly share code, notes, and snippets.

@anon987654321
Last active June 13, 2020 22:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anon987654321/15511ba53a0a13ac135ff08b0fdff24e to your computer and use it in GitHub Desktop.
Save anon987654321/15511ba53a0a13ac135ff08b0fdff24e to your computer and use it in GitHub Desktop.
#!/usr/bin/env zsh
#
# 11038420120702 BACKS UP IMPORTANT FOLDERS
#
# Requires: md5deep64
#
# backup [-t]
#
# -t Simulate backup
# Archive whole folders
# foo/ => foo_YYYYMMDD.tgz
# bar/ => bar_YYYYMMDD.tgz
folders=(sh typ usr var)
# Folders so big their subfolders should be archived separately
# foo/sub1/ => foo_sub1_YYYYMMDD.tgz
# foo/sub2/ => foo_sub2_YYYYMMDD.tgz
subfolders=(biz prd)
destination=__backup
purged=$destination/__purged
# Expand folders
all_folders=($folders $^subfolders/*(/N))
# Dependency check
function die {
print >&2 "$@"
exit 1
}
for command in md5deep64; do
(( ${+commands[$command]} )) || failed+=($command)
done
if (( $#failed )); then
die "Not found: $failed"
fi
date=$(print -P %D{%Y%m%d})
# Enable testing
case $1 in
(-t|--test) typeset test ;;
esac
for folder ($all_folders) {
prefix=${subfolders[(r)${folder:h}]:t}
# Create and/or compare manifests
manifest=${destination}/${prefix:+${prefix}_}${folder:t}.md5
md5deep64 -r -o f $folder | sort -k2 > ${manifest}.tmp || {
die "Couldn't create manifest ${manifest}.tmp"
}
if [[ -e $manifest ]] && diff >/dev/null -q $manifest ${manifest}.tmp; then
if ! (( $+test )); then
echo "Skipping $folder..."
fi
rm ${manifest}.tmp
continue
fi
if (( $+test )); then
echo "md5deep64 -r $folder | sort -k2 > ${manifest}.tmp"
fi
# If there's an existing backup, purge it
existing=($destination/${prefix:+${prefix}_}${folder:t}_*.tgz(N))
if ! (( $+test )) && (( $#existing )); then
mv -b $existing $purged || {
die "Couldn't purge $existing into $purged"
}
else
(( $#existing )) && echo "mv -b $existing $purged"
fi
# Same with the manifest
if ! (( $+test )) && [[ -e $manifest ]]; then
mv -b $manifest ${purged}/${manifest:t:r}_${date}.md5 || {
die "Couldn't purge $manifest into $purged"
}
else
[[ -e $manifest ]] && echo "mv -b $manifest ${purged}/${manifest:t:r}_${date}.md5"
fi
# Create the new backup
if ! (( $+test )); then
tar czf ${destination}/${prefix:+${prefix}_}${folder:t}_${date}.tgz $folder
echo "${destination}/${prefix:+${prefix}_}${folder:t}_${date}.tgz"
# Put the new manifest in place
mv $manifest{.tmp,} || {
die "Couldn't rename the new manifest to $manifest"
}
else
echo "tar czf ${destination}/${prefix:+${prefix}_}${folder:t}_${date}.tgz $folder"
fi
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment