diff options
Diffstat (limited to 'rsync-backup.sh')
-rwxr-xr-x | rsync-backup.sh | 299 |
1 files changed, 0 insertions, 299 deletions
diff --git a/rsync-backup.sh b/rsync-backup.sh deleted file mode 100755 index 0c48018..0000000 --- a/rsync-backup.sh +++ /dev/null @@ -1,299 +0,0 @@ -#!/bin/bash -# -# rsync-backup.sh - a backup script using rsync. -# -# Copyright 2015 - 2018 Einhard Leichtfuß -# -# This file is part of rsync-backup. -# -# rsync-backup is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# rsync-backup is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with rsync-backup. If not, see <https://www.gnu.org/licenses/>. -# - -RSYNC=rsync - -typeset -a rsync_args -typeset -a rsync_inc_args -typeset -A bakpath -typeset filter_file_all # Applied after specific filter. -typeset -A filter_file - -# Default arguments for rsync (-rptogAXlHS, --timeout, --info). -rsync_args=( - --recursive - --perms --times --owner --group - --acls --xattrs - --links - --hard-links - --sparse - --timeout=60 - #-vv - --info=progress2 - ) - -# Supplemental arguments for rsync; only used when an actual incremental -# update is performed, i.e. when --link-dest is used. -rsync_inc_args=( - --fuzzy --fuzzy - ) - -filter_file_all=/etc/rsync-backup/filter - -config=/etc/rsync-backup/backup.conf -source "$config" - -src=/home/respiranto/txt/bash/rsync-backup/src -dest=/home/respiranto/txt/bash/rsync-backup/dest - -typeset -l reply -typeset -i i n - -# RSYNC args. -# basic args: --recursive --perms --times --owner --group --links -# extra args: --sparse --acls --xattrs --hard-links --timeout=60 -# --fuzzy --fuzzy -# --filter="merge <file>" -# likely: --compress -# --partial{,dir=DIR} -# --progress -# possibly: --devices --specials -# --max-size=SIZE-OF-FILE -# --one-file-system -# --log-file=FILE --log-file-format=FORMAT -# --human-readable -# unlikely: --omit-{dir,link}-times --update (!--inplace) --delete -# --exclude -# great: --link-dest=DIR (timestamps?) -# testing: --verbose --dry-run (-vn) -# interesting: --sockopts --itemize-changes --out-format=FORMAT -# --stats - -function main -{ - # In case of a non-matching wildcard, return nothing. - shopt -s nullglob - # Include dotfiles (except . and ..) in regex matching. - shopt -s dotglob - - get_args "$@" || return $? - - check_paths || return $? - - # Change the separation char to $'\n' to avoid confusion with filenames - # containing spaces (default is $' \t\n'). - IFS=$'\n' - - find_existing_backup_dirs || return $? - - perform_backup || return $? - - refresh_symlinks || return $? -} - - -function get_args -{ - if [ $# -eq 0 ] - then - echo "Usage: $0 <src> [<dest>]" - return 1 - fi - - dirpath="$(realpath "$1")" - - if [ $# -gt 1 ] - then - bakpath="$(realpath $2)" - elif test -v bakpath[$dirpath] - then - bakpath="${bakpath[$dirpath]}" - else - echo "Error: Backup path for $dirpath not configured." - return 1 - fi - - filter_args=() - if test -v filter_file[$dirpath] && test -f "${filter_file[$dirpath]}" - then - filter_args+=("--filter=merge ${filter_file[$dirpath]}") - fi - if test -v filter_file_all -a -f "$filter_file_all" - then - filter_args+=("--filter=merge ${filter_file_all}") - fi -} - - -function check_paths -{ - # Test whether the dirs exist already. - if ! test -d "$dirpath" - then - echo "Source (\"$dirpath\") does not exist." - return 1 - fi - - if ! test -d "$bakpath" - then - echo "Target (\"$bakpath\") does not exist." - echo -n "Do you want do create it [y/N]? " - read reply - if [[ "$reply" != "y" && "$reply" != "yes" ]] - then - return 1 - fi - - if ! mkdir -p "$bakpath" - then - echo "Backup creation has failed." - echo "\"$bakpath\" could not be created." - return 1 - fi - fi -} - - -function find_existing_backup_dirs -{ - n=0 - for file in `ls "$bakpath"`; do - if test -d $bakpath/$file \ - && [[ "$file" =~ ^[0-9]{4}-[0-1][0-9]-[0-3][0-9]_[0-2][0-9]([0-5][0-9]){2}.backup$ ]] - then - dirs[n]="$file" - n+=1 - fi - done -} - - -# $1 path -# $2 error message: string -function clear_file -{ - if test -e "$1" -o -L "$1"; then - echo "It seems like the last backup process failed or you have created" \ - "the file \"$1\" manually." - echo -n "Do you want to delete it [y/N]? " - read reply - if [[ "$reply" == "y" || "$reply" == "yes" ]] - then - printf "Deleting" - if rm -rf "$1"; then - printf " - done\n" - return 0 - else - printf '\n%s\n' "$2" - printf 'The file \"%s\" could not be deleted.\n' "$1" - return 1 - fi - else - printf '%s\n' "$2" - printf '%s %s\n' "Please remove the above mentioned file manually" \ - "or run this script once more." - return 1 - fi - fi - return 0 -} - - -function perform_backup -{ - bakdate=`date +%Y-%m-%d_%H%M%S.backup` - finaldir="$bakpath/$bakdate" - tempdir="$bakpath/new.backup" - clear_file "$tempdir" "Backup creation has failed." || return 1 - clear_file "$finaldir" "Backup creation has failed." || return 1 - - # note: $n == ${#dirs[@]} - printf 'Starting backup nr. %u.\n' "$n" - if [ $n -eq 0 ] - then - # Perform first backup, not incremental. - $RSYNC "${rsync_args[@]}" \ - "${filter_args[@]}" \ - "$dirpath"/ "$tempdir" \ - || return 1 - else - # Perform incremental backup on the basis of the last. - $RSYNC "${rsync_args[@]}" \ - "${rsync_inc_args[@]}" --link-dest="${bakpath}/${dirs[n-1]}" \ - "${filter_args[@]}" \ - "$dirpath"/ "$tempdir" \ - || return 1 - fi - - mv "$tempdir" "$finaldir" || return 1 - printf '\nCreating of backup nr. %u succesfully executed.\n' "$n" -} - - -function refresh_symlinks -{ - linkdir="$bakpath/latest" - if test -L "$linkdir" - then - rm "$linkdir" - ln -s "$bakdate" "$linkdir" - elif clear_file "$linkdir" "Creation of softlink \"$linkdir\" failed." - then - ln -s "$bakdate" "$linkdir" - fi - - # by_number - numdir="$bakpath/by_number" - if ! test -d "$numdir" - then - if clear_file "$numdir" "Creating directory $numdir failed." - then - mkdir "$numdir" - else - return 1 - fi - fi - - for file in "$numdir"/* - do - if test -L "$file" - then - rm "$file" - else - if ! clear_file "$file" "Setting up numbered softlinks failed." - then - return 1 - fi - fi - done - - dirs[$n]="$bakdate" # Set last dir on current. - - max_digits=${#n} - zeros[max_digits]='' - i=$max_digits-1 - while [ $i -ge 1 ] - do - zeros[i]=${zeros[i+1]}0 - i+=-1 - done - - i=0 - while [ $i -le $n ] - do - ln -s "../${dirs[i]}" "$numdir/${zeros[${#i}]}$i" - i+=1 - done -} - - -main "$@" |