Last active
May 15, 2018 10:32
-
-
Save lhns/f13c07e4350c2408f5af7f00c2800a82 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# path to tar file | |
# 1 input: path | |
# stdout: tar file | |
pathToTar() { | |
path="$1" | |
if [[ "$path" == /* ]] | |
then | |
tar -cf - --ignore-failed-read -C / "${path:1}" | |
else | |
tar -cf - --ignore-failed-read "$path" | |
fi | |
} | |
# tar file to path | |
# 1 output: path | |
# stdin: tar file | |
tarToPath() { | |
tar -C "$1" -xf - | |
} | |
# convert file to hex file | |
# stdin: file | |
# stdout: hex file | |
toHex() { | |
xxd -ps -c 8 | |
} | |
# convert hex file to file | |
# stdin: hex file | |
# stdout: file | |
fromHex() { | |
xxd -r -ps | |
} | |
# file1 -> bin diff -> file2 | |
# 1 input: file1 | |
# 2 input: file2 | |
# stdout: bin diff | |
binDiff() { | |
diff <(cat "$1" | toHex) <(cat "$2" | toHex) | compress | |
} | |
# file1 -> bin diff -> file2 | |
# stdin: bin diff | |
# 1 input: file1 | |
# stdout: file2 | |
applyBinDiff() { | |
tmpfile="$(mktemp)" | |
cat "$1" | toHex > "$tmpfile" | |
decompress | patch -N -o - "$tmpfile" 2>/dev/null | fromHex | |
rm "$tmpfile" | |
} | |
# file to compressed file | |
# stdin: file | |
# stdout: compressed file | |
compress() { | |
gzip | |
} | |
# compressed file to file | |
# stdin: compressed file | |
# stdout: file | |
decompress() { | |
gunzip | |
} | |
# 1 input: backup path | |
# stdout: full backup archive | |
pathToFullBackup() { | |
pathToTar "$1" | tee >(wc -c >&2) | compress | tee >(wc -c >&2) | |
} | |
# stdin: full backup archive | |
# 1 input: backup path | |
# stdout: diff backup archive | |
pathToDiffBackup() { | |
decompress | binDiff - <(pathToTar "$1" | tee >(wc -c >&2)) | tee >(wc -c >&2) | |
} | |
# stdin: diff backup archive | |
# 1 input: full backup archive | |
# stdout: full backup tar | |
diffToFullBackupTar() { | |
applyBinDiff <(cat "$1" | decompress) | |
} | |
# Usage: | |
# backup [path] [archive]: create full backup | |
# backup -d [full backup] [path] [archive]: create differential backup | |
# backup -r [path] [archive]: restore full backup | |
# backup -r -d [full backup] [path] [archive]: restore differential backup | |
# Cron example: | |
# 0 1 1 * * backup "/etc" "/var/backup-full-$(date '+%Y%m%d%H%M%S')" | |
# 0 4 * * * backup -d "/var/$(ls -1 "/var" | grep "backup-full-" | sort -rn | head -1)" "/etc" "/var/backup-$(date '+%Y%m%d%H%M%S')" | |
if [[ "$1" == "-r" ]]; then | |
# restore | |
shift | |
if [[ "$1" == "-d" ]]; then | |
# differential | |
fullBackupPath="$2" | |
shift 2 | |
cat "$2" | diffToFullBackupTar "$fullBackupPath" | tarToPath "$1" | |
else | |
# full | |
cat "$2" | decompress | tarToPath "$1" | |
fi | |
else | |
# create | |
log=$(( | |
if [[ "$1" == "-d" ]]; then | |
# differential | |
fullBackupPath="$2" | |
shift 2 | |
cat "$fullBackupPath" | pathToDiffBackup "$1" > "$2" | |
else | |
# full | |
pathToFullBackup "$1" > "$2" | |
fi | |
) 3>&2 2>&1 1>&3) 2>&1 | |
sizePre=$(echo "$log" | cut -d $'\n' -f 1) | |
sizePost=$(echo "$log" | cut -d $'\n' -f 2) | |
echo "Size before compression: $sizePre" | |
echo "Size after compression: $sizePost" | |
echo "Compression ratio: $(( $sizePre / $sizePost ))" | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment