add file type, option -a to find file from different machine.

This commit is contained in:
2022-07-22 11:53:11 +02:00
parent d7a06202f9
commit db48925066

View File

@@ -16,16 +16,24 @@
# sync-view.sh - list file versions from rsync.sh backups. # sync-view.sh - list file versions from rsync.sh backups.
# #
# SYNOPSIS # SYNOPSIS
# sync-view.sh [OPTIONS] FILE # sync-view.sh [OPTIONS] TARGET
# #
# DESCRIPTION # DESCRIPTION
# List FILE versions from a sync.sh backup directory. # List TARGET versions from a sync.sh backup directory.
# #
# OPTIONS # OPTIONS
# -1, --unique # -1, --unique
# Skip duplicate files. This option do not apply if FILE is a # Skip duplicate files. This option do not apply if TARGET is a
# directory. # directory.
# #
# -a, --absolute-target
# Do not try to resolve TARGET path.. By default, the script will try to
# guess TARGET absolute path. This is not possible if current system is
# different from the the one from which the backup was made, or if some
# path component are missing or were changed.
# If this option is used, TARGET must be an absolute path as it was on
# backuped machine.
#
# -b, --backupdir=DIR # -b, --backupdir=DIR
# DIR is the local mount point where the backups can be found. It can # DIR is the local mount point where the backups can be found. It can
# be a network mount, or the destination directory if the backup was # be a network mount, or the destination directory if the backup was
@@ -87,6 +95,7 @@ BACKUPDIR="" # the local view of backup dir
TARGETDIR="" # temp dir to hold links TARGETDIR="" # temp dir to hold links
TARGET="" # the file/dir to find TARGET="" # the file/dir to find
RESOLVETARGET=y # resolve TARGET
UNIQUE="" # omit duplicate files UNIQUE="" # omit duplicate files
EXCLUDE="" # regex for files to exclude EXCLUDE="" # regex for files to exclude
VERBOSE="" # -v option VERBOSE="" # -v option
@@ -97,7 +106,7 @@ set -o errexit
#set -o xtrace #set -o xtrace
usage() { usage() {
printf "usage: %s [-b BACKUPDIR][-c CONF][-d DSTDIR][-r ROOTDIR][-x EXCLUDE][-1hmv] file\n" "$CMDNAME" printf "usage: %s [-b BACKUPDIR][-c CONF][-d DSTDIR][-r ROOTDIR][-x EXCLUDE][-1ahmv] file\n" "$CMDNAME"
return 0 return 0
} }
@@ -127,7 +136,8 @@ log() {
;; ;;
t) timestr=$(date "+%F %T%z ") t) timestr=$(date "+%F %T%z ")
;; ;;
*) ;; *)
;;
esac esac
done done
shift $((OPTIND - 1)) shift $((OPTIND - 1))
@@ -139,11 +149,30 @@ log() {
return 0 return 0
} }
filetype() {
local file="$1" type="unknown"
if [[ ! -e "$file" ]]; then
type="missing"
elif [[ -f "$file" ]]; then
type="file"
elif [[ -d "$file" ]]; then
type="directory"
elif [[ -h "$file" ]]; then
type="symlink"
elif [[ -p "$file" ]]; then
type="fifo"
elif [[ -b "$file" || -c "$file" ]]; then
type="device"
fi
printf "%s" "$type"
return 0
}
# command-line parsing / configuration file read. # command-line parsing / configuration file read.
parse_opts() { parse_opts() {
# short and long options # short and long options
local sopts="1b:c:d:hmr:vx:" local sopts="1ab:c:d:hmr:vx:"
local lopts="unique,backupdir:,config:,destdir:,help,man,root:,verbose,exclude:" local lopts="absolute-target,unique,backupdir:,config:,destdir:,help,man,root:,verbose,exclude:"
local tmp tmp_destdir="" tmp_destdir="" tmp_rootdir="" config local tmp tmp_destdir="" tmp_destdir="" tmp_rootdir="" config
if ! tmp=$(getopt -o "$sopts" -l "$lopts" -n "$CMD" -- "$@"); then if ! tmp=$(getopt -o "$sopts" -l "$lopts" -n "$CMD" -- "$@"); then
@@ -158,6 +187,9 @@ parse_opts() {
-1|--unique) -1|--unique)
UNIQUE=yes UNIQUE=yes
;; ;;
'-a'|'--absolute-target')
RESOLVETARGET=""
;;
'-b'|'--backupdir') '-b'|'--backupdir')
tmp_backupdir="$2" tmp_backupdir="$2"
shift shift
@@ -200,7 +232,6 @@ parse_opts() {
shift shift
break break
;; ;;
*) *)
usage usage
log 'Internal error!' log 'Internal error!'
@@ -215,8 +246,12 @@ parse_opts() {
# to find the relative path of TARGET in backup tree. # to find the relative path of TARGET in backup tree.
# it may also contain BACKUPDIR variable, which the local root of backup # it may also contain BACKUPDIR variable, which the local root of backup
# tree. # tree.
(( $# != 1 )) && ! usage if (( $# != 1 )); then
TARGET="$(realpath -L "$1")" usage
exit 1
fi
TARGET="$1"
[[ -z $RESOLVETARGET ]] && TARGET="$(realpath -L "$1")"
[[ -n "$tmp_backupdir" ]] && BACKUPDIR="$tmp_backupdir" [[ -n "$tmp_backupdir" ]] && BACKUPDIR="$tmp_backupdir"
[[ -n "$tmp_destdir" ]] && TARGETDIR="$tmp_destdir" [[ -n "$tmp_destdir" ]] && TARGETDIR="$tmp_destdir"
@@ -262,8 +297,8 @@ check_paths() {
log "ROOTDIR=[%s]" "$ROOTDIR" log "ROOTDIR=[%s]" "$ROOTDIR"
log "BACKUPDIR=[%s]" "$BACKUPDIR" log "BACKUPDIR=[%s]" "$BACKUPDIR"
log "TARGETDIR=[%s]" "$TARGETDIR" log "TARGETDIR=[%s]" "$TARGETDIR"
log "FILE=[%s]" "$TARGET" log "TARGET=[%s]" "$TARGET"
return 0
} }
parse_opts "$@" parse_opts "$@"
@@ -279,15 +314,17 @@ for file in "${DIRS[@]}"; do
_tmp=${TARGET#"$ROOTDIR"} _tmp=${TARGET#"$ROOTDIR"}
[[ $_tmp =~ ^/.*$ ]] || _tmp="/$_tmp" [[ $_tmp =~ ^/.*$ ]] || _tmp="/$_tmp"
src="$file$_tmp" src="$file$_tmp"
#printf "src=%s\n" "$src"
if [[ ! -e $src ]]; then if [[ ! -e $src ]]; then
log "Skipping non-existing %s" "$src" log "Skipping non-existing %s" "$src"
continue continue
fi fi
#ls -lLi "$src" #ls -li "$src"
# last modification time in seconds since epoch # last modification time in seconds since epoch
inode=$(stat --dereference --printf="%i\n" "$src") inode=$(stat --dereference --printf="%i" "$src")
date=$(stat --dereference --printf="%Y\n" "$src") date=$(stat --printf="%Y" "$src")
date_backup=$(stat --dereference --printf="%Y" "$file")
# target is daily-01, etc... # target is daily-01, etc...
#target=$(date --date="@$date" "+%Y-%m-%d %H:%M")" - ${file#"$BACKUPDIR/"}" #target=$(date --date="@$date" "+%Y-%m-%d %H:%M")" - ${file#"$BACKUPDIR/"}"
target="${file#"$BACKUPDIR/"}" target="${file#"$BACKUPDIR/"}"
@@ -298,24 +335,37 @@ for file in "${DIRS[@]}"; do
continue continue
fi fi
if [[ -z $UNIQUE || ! -v INODES[$inode] ]]; then if [[ -z $UNIQUE || ! -v INODES[$inode] ]]; then
log "Adding inode %s (%s)" "$inode" "$target" log "Adding %s inode %s (%s)" "$file" "$inode" "$target"
ln -fs "$src" "$TARGETDIR/$target" ln -fs "$src" "$TARGETDIR/$target"
else else
log "Skipping duplicate inode %s (%s)" "$inode" "$target" log "Skipping duplicate inode %s (%s)" "$inode" "$target"
fi fi
INODES[$inode]=${INODES[$inode]:-$date} INODES[$inode]=${INODES[$inode]:-$date}
INODES[backup-$inode]=${INODES[backup-$inode]:-$date_backup}
done done
if [[ -n "$(ls -A .)" ]]; then if [[ -n "$(ls -A .)" ]]; then
printf "mod time|backup|inode|size|perms|path\n" printf "type|modified|inode|size|perms|backup|backup date|path\n"
# for file in {dai,week,month,year}ly-[0-9][0-9]; do # for file in {dai,week,month,year}ly-[0-9][0-9]; do
for file in *; do for symlink in *; do
inode=$(stat --dereference --printf="%i" "$file") file=$(readlink "$symlink")
printf "file=<%s> link=<%s>\n" "$file" "$symlink" >&2
inode=$(stat --printf="%i" "$file")
type=$(filetype "$file")
#links=$(stat --printf="%h" "$file")
date=$(date --date="@${INODES[$inode]}" "+%Y-%m-%d %H:%M") date=$(date --date="@${INODES[$inode]}" "+%Y-%m-%d %H:%M")
size=$(stat --dereference --printf="%s" "$file") backup_date=$(date --date="@${INODES[backup-$inode]}" "+%Y-%m-%d %H:%M")
perms=$(stat --dereference --printf="%A" "$file") size=$(stat --printf="%s" "$file")
path=$(readlink "$file") perms=$(stat --printf="%A" "$file")
printf "%s|%s|%s|%s|%s|%s\n" "$date" "$file" "$inode" "$size" "$perms" "$path" printf "%s|" "$type"
printf "%s|" "$date"
#printf "%s|" "$links"
printf "%s|" "$inode"
printf "%s|" "$size"
printf "%s|" "$perms"
printf "%s|" "$symlink"
printf "%s|" "$backup_date"
printf "%s\n" "$file"
# ls -lrt "$TARGETDIR" # ls -lrt "$TARGETDIR"
done | sort -r done | sort -r
fi | column -t -s\| fi | column -t -s\|