#!/usr/bin/env bash # # Archive all files in source directory into destination directory. set -euo pipefail # Parse command-line arguments. unset SRCDIR DESTDIR BASENAME while getopts 's:d:n:' arg; do case "${arg}" in s) SRCDIR="${OPTARG}" ;; d) DESTDIR="${OPTARG}" ;; n) BASENAME="${OPTARG}-" ;; *) echo "Unknown argument '${arg}' given. Exiting." >&2 && exit 1 ;; esac done # Check and return true if source files are newer than any archive already created. function archive-should-update() { local latest="${DESTDIR}/${BASENAME}latest.tar.gz" if ! test -e "${latest}"; then return 0 elif test "$(find "${SRCDIR}" -type f -newer "${latest}" -print -quit | wc -l)" -gt 0; then return 0 fi return 1 } # Create compressed archive for source path into destination path for pre-defined, date-based name. function archive-create() { local name="${BASENAME}$(date +%w%H)" # Create uncompressed archive for source path and compress separately to ensure minimal blocking. tar --verbose --create --file "${DESTDIR}/${name}.tar" --directory "${SRCDIR}" . gzip --force "${DESTDIR}/${name}.tar" # Point the latest archive to a "special" name for future use. (cd /backup && ln --symbolic --force "${name}.tar.gz" "${BASENAME}latest.tar.gz") } # Entry-point for script. Create tar archive for source directory into destination directory, checking # for any changes since last run, and ensuring files are archived correctly for subsequent restore. function main() { if archive-should-update "${SRCDIR}" "${DESTDIR}"; then archive-create "${SRCDIR}" "${DESTDIR}" fi } main "$@"