Initial commit
This commit is contained in:
commit
20fcf2fac6
145
backup-rclone.sh
Executable file
145
backup-rclone.sh
Executable file
|
@ -0,0 +1,145 @@
|
||||||
|
#!/bin/bash
|
||||||
|
MAX_NAME_WIDTH=50 # Maximal length of name next to the progress bar in percent (%)
|
||||||
|
|
||||||
|
tempdir=$(mktemp -d /tmp/backup-XXXXXXXXXX)
|
||||||
|
existing=()
|
||||||
|
|
||||||
|
recursive_backup() {
|
||||||
|
|
||||||
|
hashtemp=$(mktemp $tempdir/hashes-XXXXXXXXXXXXXXX.db) # /tmp dir for saving data and encrypting files
|
||||||
|
if [[ -n $(rclone lsf "backup:$hashdb" 2>/dev/null) ]]; then # if hash file exists, copy it to tmp dir
|
||||||
|
rclone cat "backup:$hashdb" > $hashtemp
|
||||||
|
fi
|
||||||
|
trap "cleanup $hashtemp $hashdb" SIGINT
|
||||||
|
trap "cleanup $hashtemp $hashdb" SIGTSTP
|
||||||
|
|
||||||
|
for dir in "${include[@]}"; do # go through all included directories
|
||||||
|
done_files=0
|
||||||
|
progress=0
|
||||||
|
total_files=$(wc -l <<<$(find "$dir" -type f)) # count all files for progress bar
|
||||||
|
action=""
|
||||||
|
for i in "${exclude[@]}"; do if [[ "$dir" == "$i" ]]; then continue; fi; done # if dir in exclude, skip it # TODO: POSSIBLE WHOOPSIE!
|
||||||
|
while read k; do # take every file and make a backup
|
||||||
|
if [[ ${k///} == $k ]]; then filepath="."; else filepath=${k%/*}; fi # if file in root of dir, change the path to not crash everything ,else get filepath
|
||||||
|
draw_progress $(($progress)) "$k" "$action"
|
||||||
|
#remotehash="$(cat $hashtemp | grep -n "$k")" # old databese
|
||||||
|
sqlcommand="SELECT hash FROM files WHERE backpath=\"${k}\""
|
||||||
|
remotehash="""$(sqlite3 $hashtemp "$sqlcommand")""" # get hash from database
|
||||||
|
if [[ -z $remotehash ]]; then entryexists=false; else entryexists=true; fi # if file entry (and hash) exists, save as bool
|
||||||
|
localhash="$(md5sum "$k")" # hash of local version of file
|
||||||
|
done_files=$(($done_files+1))
|
||||||
|
progress=$(($done_files*100/$total_files))
|
||||||
|
if [[ "$remotehash" == "$localhash" ]]; then action="Skip"; continue; fi # if the has his the same, skip backuup
|
||||||
|
action="Backup"
|
||||||
|
draw_progress $(($progress)) "$k" "$action"
|
||||||
|
if [[ $enctype == "gpg" ]]; then
|
||||||
|
gpg -e -r "$RECIPIENT_ID" -o "$tempdir/${k##*/}.gpg" "$k"
|
||||||
|
backupfile="$tempdir/${k##*/}.gpg"
|
||||||
|
else
|
||||||
|
backupfile="$k"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $filepath == "." ]]; then flpth=""; else flpth="/$filepath"; fi
|
||||||
|
backup "$backupfile" "backup:$backdir$flpth"
|
||||||
|
done <<< "$(find "$dir" -type f)"
|
||||||
|
done
|
||||||
|
touch missing-files.txt
|
||||||
|
while read i; do # TODO: DELETE THIS PART
|
||||||
|
sfile="${i#* }"
|
||||||
|
if [[ -f "$sfile" ]]; then df="Hi"; else echo "Missing: $sfile"; echo "$sfile" >> missing-files.txt; fi
|
||||||
|
done <<<$(cat $hashtemp)
|
||||||
|
cleanup $hashtemp $hashdb
|
||||||
|
}
|
||||||
|
backup() { # backup 1:<file> 2:<remotedir>
|
||||||
|
if [[ *"${existing[@]}"* == "$2" ]]; then # if remote directory is set as existing, don't check it's existence
|
||||||
|
df="Hi"
|
||||||
|
else
|
||||||
|
if [[ -n $(rclone lsd "$2" 1>/dev/null) ]]; then # check if directory doesn't exist on server
|
||||||
|
rclone mkdir "$2"
|
||||||
|
fi
|
||||||
|
existing=("${existing[@]}" "$2")
|
||||||
|
fi
|
||||||
|
bool=0
|
||||||
|
rclone copy "$1" "$2" && bool=1
|
||||||
|
#if [[ $remoteline == "0" && $bool == 1 ]]; then echo "$localhash" >> $hashtemp; else sed -i "${remoteline}s|.*|${localhash}|" $hashtemp; fi # TODO: SQL ######
|
||||||
|
if [[ $bool==1 && $entryexists ]]; then
|
||||||
|
sqlcommand="UPDATE files SET hash=\"${localhash}\" WHERE backpath=\"${2}\"" #set new hash in database
|
||||||
|
sqlite3 $hashtemp "$sqlcommand"
|
||||||
|
else
|
||||||
|
if [[ "$enctype" == "gpg" ]]; then encdata="$RECIPIENT_ID"
|
||||||
|
else encdata=""; fi
|
||||||
|
sqlcommand="INSERT INTO files(backpath,localroot,hash,backupenc,encdata) VALUES(\'${2}\',\'$(pwd)\',\'$localhash\',\'${enctype}\',\'${encdata}\')"
|
||||||
|
sqlite3 $hashtemp "$sqlcommand"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
cleanup() { # 1:hashtemp 2:hashdb
|
||||||
|
echo -e "\ncleaning up..."
|
||||||
|
cd ${1%/*}
|
||||||
|
localhfile=${2##*/}
|
||||||
|
mv "${1##*/}" "$localhfile"
|
||||||
|
rclone move "$localhfile" backup:${2%/*}
|
||||||
|
finish
|
||||||
|
}
|
||||||
|
finish() {
|
||||||
|
rmdir $tempdir || rm -rf $tempdir
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
draw_progress() { # draw_progress 1:<done_progress> 2:<filename> 3:<Action>
|
||||||
|
|
||||||
|
window_length=$(tput cols); window_length=$(($window_length-3)) # get max window length
|
||||||
|
max_name_length=$(($window_length*$MAX_NAME_WIDTH/100)) # calc max length of filepath
|
||||||
|
if [[ ${#2} -gt $max_name_length ]]; then # if filepath too long, cut it, else add whitespace
|
||||||
|
name="$(cut -c -$max_name_length <<< "$2")"
|
||||||
|
else
|
||||||
|
name="$2"
|
||||||
|
if [[ ${#name} -lt $max_name_length ]]; then
|
||||||
|
for _ in $(seq ${#name} $max_name_length); do name+=" "; done
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
window_length=$(($window_length-${#name})) # get length of progress bar
|
||||||
|
prog=$(($1*$window_length/100))
|
||||||
|
tot=$((window_length-1))
|
||||||
|
#echo -e "prog $prog tot $tot done $1 total $2 win $window_length"; return
|
||||||
|
|
||||||
|
# Delete the last two lines
|
||||||
|
printf "\033[3K"
|
||||||
|
# Restore the cursor position
|
||||||
|
printf "\033[u"
|
||||||
|
echo "Progress: $progress% Action: $3 "
|
||||||
|
printf "["
|
||||||
|
for _ in $(seq 1 $prog); do
|
||||||
|
printf "#"
|
||||||
|
done
|
||||||
|
for _ in $(seq $prog $tot); do
|
||||||
|
printf "-"
|
||||||
|
done
|
||||||
|
printf "]$name\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if [[ $# -eq 0 ]]; then
|
||||||
|
echo "Please select a directory for backup!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd $1
|
||||||
|
curdir=$(pwd)
|
||||||
|
# save cursor position
|
||||||
|
printf "\033[s"
|
||||||
|
# print two dummy lines
|
||||||
|
printf "\n\n"
|
||||||
|
|
||||||
|
if [[ $# -eq 1 ]]; then
|
||||||
|
if [[ -f ".backup.env" ]]; then
|
||||||
|
source .backup.env
|
||||||
|
if [[ -z ${backdir+x} || -z ${hashdb+x} ]]; then echo "ERROR: env-file doesn't hold needed variables!"; exit; fi
|
||||||
|
if [[ -n ${include+x} ]]; then include+=(".backup.env"); else include=(*); fi
|
||||||
|
if [[ -z ${exclude+x} ]]; then exclude=("uc3rumcr3urc34u09q347c7055030785c3cc30mq3rcmu83qm3m.notanonionlink"); fi
|
||||||
|
if [[ -z ${enctype+x} ]]; then enctype="plain"; fi
|
||||||
|
else echo "ERROR: env-file doesn't exist!!"; exit; fi
|
||||||
|
else
|
||||||
|
echo "too many args!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
rmdir $tempdir ||rm -rf $tempdir
|
9
example.backup.env
Normal file
9
example.backup.env
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
enctype="gpg" # type of encryption, use plain if the share is already encrypted (gpg,plain)
|
||||||
|
|
||||||
|
#include=("supersecretfiles" "a-folder") # include these folders in the backup (optional)
|
||||||
|
#exclude=(".thumbnails" ".git") # exclude these folders from the backup (optional)
|
||||||
|
|
||||||
|
backdir="marcel/archive" # directory on the rclone server
|
||||||
|
hashdb="$backdir/hashes.db" # database file on the rclone server
|
||||||
|
|
||||||
|
RECIPIENT_ID="123ABF84D7FAADB09015825F9231CC1FF5F1E5D2" # needed if enctype="gpg"
|
Loading…
Reference in a new issue