Easily archive entire directories in whichever manner you wish.
at main 96 lines 2.8 kB view raw
1#!/usr/bin/env bash 2# dependencies: 3# tar, xz, stat, par2create (from par2cmdline package), md5sum, du, awk, jq 4set -e 5 6check_command() { 7 CMD="$1" 8 9 if ! command -v "$CMD" 2>&1 /dev/null 10 then 11 gum log -l "fatal" "Executable: $CMD was not found." 12 exit 1 13 fi 14} 15 16gum log -t kitchen -l info "Checking for dependencies:" 17check_command awk 18check_command du 19check_command find 20check_command jq 21check_command md5sum 22check_command par2create 23check_command stat 24check_command tar 25check_command xz 26gum log -t kitchen -l info "All dependencies found!" 27 28ARCHIVE_DB="$HOME"/.local/state/archives.json 29 30create_archive() { 31 ARCHIVE_NAME="$1" 32 ARCHIVE_DESTINATION="$2" 33 TARGET="$3" 34 35 gum log -t kitchen -l info "Creating tar for $TARGET." 36 tar cfP "$ARCHIVE_NAME".tar "$TARGET" 37 mv "$ARCHIVE_NAME".tar "$ARCHIVE_DESTINATION" 38 gum log -t kitchen -l info "Finished creating tar for $TARGET." 39 40 gum log -l info "Proceeding to archive." 41 cd "$ARCHIVE_DESTINATION" || exit 0 42 [ -f "$ARCHIVE_NAME".tar.xz ] && rm "$ARCHIVE_NAME".tar.xz && gum log -t kitchen -l info "Removed old $ARCHIVE_NAME.tar.xz." 43 44 gum log -l info -t kitchen "Compressing: $ARCHIVE_NAME.tar" 45 xz -v -e -9 "$ARCHIVE_NAME".tar 46 47 DIR_SIZE="$(du -sh "$TARGET" | awk '{print $1}')" 48 ARCHIVE_SIZE="$(du -sh "$ARCHIVE_NAME".tar.xz | awk '{print $1}')" 49 gum log -l info -t kitchen "Finished archiving $TARGET." 50 gum style --bold "Compressed $TARGET ($DIR_SIZE) to $ARCHIVE_NAME ($ARCHIVE_SIZE)." 51} 52 53create_parchive() { 54 gum log -l info -t kitchen "Creating parity archive." 55 ARCHIVE="$1" 56 find . -name '*par2' -exec rm {} \; 57 par2create -r30 -n1 "$ARCHIVE" 58} 59 60update_json() { 61 INDEX="$1" 62 ARCHIVE_TIME="$2" 63 UPLOAD_TIME="$3" 64 MD5SUM="$4" 65 66 FOO="$(jq ".[$INDEX].timestamps.last_archive = $ARCHIVE_TIME" < "$ARCHIVE_DB" \ 67 | jq ".[$INDEX].timestamps.last_upload = $UPLOAD_TIME" \ 68 | jq ".[$INDEX].md5sum = \"$MD5SUM"\")" 69 echo "$FOO" > "$ARCHIVE_DB" 70} 71 72ARCHIVE_COUNT="$(jq '.[].name' < "$ARCHIVE_DB" | wc -l)" 73ARCHIVE_COUNT="$((ARCHIVE_COUNT - 1))" 74for i in $(seq 0 "$ARCHIVE_COUNT") 75do 76 JSON="$(jq ".[$i]" < "$ARCHIVE_DB")" 77 TARGET="$(echo "$JSON" | jq -r '.target')" 78 TARGET="${TARGET/#\~/$HOME}" 79 ARCHIVE="$(echo "$JSON" | jq '.archive')" 80 ARCHIVE_NAME="$(echo "$ARCHIVE" | jq -r '.name')" 81 ARCHIVE_PATH="$(echo "$ARCHIVE" | jq -r '.destination')" 82 ARCHIVE_PATH="${ARCHIVE_PATH/#\~/$HOME}" 83 SYNC_COMMAND="$(echo "$JSON" | jq -r '.sync_command')" 84 mkdir -p "$ARCHIVE_PATH" 85 86 create_archive "$ARCHIVE_NAME" "$ARCHIVE_PATH" "$TARGET" 87 88 create_parchive "$ARCHIVE_NAME".tar.xz 89 90 ARCHIVE_TIME="$(stat -c %W "$ARCHIVE_NAME".tar.xz)" 91 MD5SUM="$(md5sum "$ARCHIVE_NAME".tar.xz | awk '{print $1}')" 92 93 bash -c "$SYNC_COMMAND"; UPLOAD_TIME="$(date +%s)" 94 95 update_json "$i" "$ARCHIVE_TIME" "$UPLOAD_TIME" "$MD5SUM" 96done