diff options
| author | David Vazgenovich Shakaryan <dvshakaryan@gmail.com> | 2026-08-01 19:30:55 -0700 |
|---|---|---|
| committer | David Vazgenovich Shakaryan <dvshakaryan@gmail.com> | 2026-08-01 19:30:55 -0700 |
| commit | 3df85966bd608863cf5ed02b85385d0b33665482 (patch) | |
| tree | 91cfe3c377fa2dc37533a6fe517f6f2a34859889 | |
| parent | 27d127a861ae9707473b2eaf77bb39fe5350fd8e (diff) | |
| download | backomp-3df85966bd608863cf5ed02b85385d0b33665482.tar.gz backomp-3df85966bd608863cf5ed02b85385d0b33665482.tar.xz | |
| -rwxr-xr-x | backomp | 53 | ||||
| -rwxr-xr-x | pre-copy-rclone-hardlink.sh | 2 |
2 files changed, 36 insertions, 19 deletions
@@ -42,7 +42,7 @@ BEGIN { wshift = (11 - arr2[opt_week_start])*24*60*60 } -!n_buckets || NR == 1 { +!n_buckets || keep_first && NR == 1 { ++keep[$0] } @@ -113,7 +113,7 @@ parse_flags() { } qargs() { - local arg str= + local arg str for arg; do [[ "${arg:-*}" =~ [^A-Za-z0-9%+./:=@_-] ]] && arg="${arg@Q}" @@ -198,7 +198,7 @@ filter() { local -n __src="${1}" __dest="${2}" local __label="${3}" __script="${4}" shift 4 - local res + local res c="${#__src[@]}" mapfile -td '' __dest < <( printf '%s\0' "${__src[@]}" | \ @@ -210,7 +210,7 @@ filter() { return 1 fi - if ((${#__src[@]})); then + if ((!DRY && c)); then exists "${__dest[0]}" && return 0 [[ "$?" -eq 1 ]] && err "${__label} returned empty or invalid list" @@ -238,10 +238,12 @@ populate() { fi if [[ "${__dir}" =~ ^([^:/]*):(.*) ]]; then - mapfile -td '' __arr < <( - ssh_run "${BASH_REMATCH[1]}" \ - "shopt -s nullglob; printf '%s\0' $( \ - printf '%q' "${BASH_REMATCH[2]}")/*") + read -rd '' cmd <<-EOF + shopt -s nullglob + x=($(printf '%q' "${BASH_REMATCH[2]}")/*) + ((!\${#x[@]})) || printf '%s\0' \"\${x[@]}\" + EOF + mapfile -td '' __arr < <(ssh_run "${BASH_REMATCH[1]}" "${cmd}") wait "$!" || return 1 __arr=("${__arr[@]/#/${BASH_REMATCH[1]}:}") @@ -249,7 +251,9 @@ populate() { fi mapfile -td '' __arr < <( - shopt -s nullglob; printf '%s\0' "${__dir}/"*) + shopt -s nullglob + x=("${__dir}/"*) + ((!${#x[@]})) || printf '%s\0' "${x[@]}") } copy() { @@ -266,6 +270,11 @@ copy() { fi done + if ((DRY)); then + echo "* DRY: copy ${dest}${link_dest:+ (link: ${link_dest})}" + return + fi + if [[ -n "${opts['pre_copy']}" ]]; then bash -c "$(declare -p src dest link_dest opts \ ); temp_dest=$(printf '%q' "${dest}.tmp" \ @@ -318,7 +327,9 @@ prune() { if [[ "${__snaps[__i]}" == "${__keep[__k]}" ]]; then ((++__k)) else - if [[ "${__snaps[__i]}" == rclone://* ]]; then + if ((DRY)); then + echo "* DRY: prune ${__snaps[__i]}" + elif [[ "${__snaps[__i]}" == rclone://* ]]; then run rclone purge -- "${__snaps[__i]#*//}" elif [[ "${__snaps[__i]}" =~ ^([^:/]*):(.*) ]]; then USE_RUN=1 ssh_run "${BASH_REMATCH[1]}" \ @@ -337,7 +348,7 @@ backup() { local rsync_flags="${6}" rclone_flags="${7}" ssh_flags="${8}" local dest_path snaps keep - if [[ ! -e "${src_path}" ]]; then + if ((!NO_BACKUP)) && [[ ! -e "${src_path}" ]]; then err "source does not exist: ${src_path}" return 1 fi @@ -348,22 +359,28 @@ backup() { populate snaps "${dest_dir}" || return 1 filter snaps snaps 'pre-snapshot awk prefilter' "${AWK_PREFILTER}" \ || return 1 - [[ -n "${snaps}" ]] && current "${snaps[0]##*/}" "${interval}" \ - && return - dest_path="${dest_dir}/$(date -u '+%Y-%m-%d-%H%M%S')" - copy "${src_path}" "${dest_path}" "${snaps[0]}" || return 1 + if ((!NO_BACKUP)) && ( [[ -z "${snaps}" ]] || + ! current "${snaps[0]##*/}" "${interval}" ); then + dest_path="${dest_dir}/$(date -u '+%Y-%m-%d-%H%M%S')" + copy "${src_path}" "${dest_path}" "${snaps[0]}" || return 1 + snaps+=("${dest_path}") + fi + + ((NO_PRUNE)) && return if [[ ! "${retain}" =~ ^( *([0-9]+|\*)\^?[hdwM])*\ *$ ]]; then err "invalid \$retain setting: ${retain}" return 1 fi - snaps+=("${dest_path}") - filter snaps snaps 'post-snapshot awk prefilter' "${AWK_PREFILTER}" \ - || return 1 + if [[ -n "${dest_path}" ]]; then + filter snaps snaps 'post-snapshot awk prefilter' \ + "${AWK_PREFILTER}" || return 1 + fi filter snaps keep 'awk filter' "${AWK_FILTER}" \ -v "opt_retain=${retain}" -v "opt_week_start=${week_start}" \ + -v "keep_first=$((!NO_BACKUP))" \ || return 1 prune snaps keep } diff --git a/pre-copy-rclone-hardlink.sh b/pre-copy-rclone-hardlink.sh index 01f7b6e..aa763b5 100755 --- a/pre-copy-rclone-hardlink.sh +++ b/pre-copy-rclone-hardlink.sh @@ -3,7 +3,7 @@ # Copyright 2023 David Vazgenovich Shakaryan qargs() { - local arg str= + local arg str for arg; do [[ "${arg:-*}" =~ [^A-Za-z0-9%+./:=@_-] ]] && arg="${arg@Q}" |
