84 lines
1.6 KiB
Bash
Executable File
84 lines
1.6 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
usage() {
|
|
echo "USAGE: $0 [--clobber] [--verbose] [--] dir zfs-dir zfsdataset@old-snap [[zfsdataset]@new-snap]"
|
|
}
|
|
|
|
verbose=
|
|
debug() {
|
|
if [ -n "$verbose" ]
|
|
then
|
|
echo "$@"
|
|
fi
|
|
}
|
|
|
|
clobber=--no-clobber
|
|
while [ "${1:0:1}" == "-" ]
|
|
do
|
|
case $1 in
|
|
--)
|
|
break
|
|
;;
|
|
--verbose)
|
|
verbose=true
|
|
;;
|
|
--clobber)
|
|
clobber=--force
|
|
;;
|
|
--no-clobber)
|
|
clobber=--no-clobber
|
|
;;
|
|
*)
|
|
>&2 echo "Unrecognized option: $1"
|
|
usage
|
|
exit 1
|
|
esac
|
|
shift
|
|
done
|
|
|
|
if (( $# < 3 ))
|
|
then
|
|
usage
|
|
exit 0
|
|
fi
|
|
|
|
root="$1"
|
|
prefix="$2"
|
|
old_snap="$3"
|
|
new_snap="$4"
|
|
|
|
if [[ "${root:0-1}" != "/" ]]
|
|
then
|
|
root="$root/"
|
|
fi
|
|
if [[ "${prefix:0-1}" != "/" ]]
|
|
then
|
|
prefix="$prefix/"
|
|
fi
|
|
echo "Target directory: $root"
|
|
echo "Source filesystem: $prefix"
|
|
echo "Old snapshot: $old_snap"
|
|
echo "New snapshot: $new_snap"
|
|
|
|
debug zfs diff -H "$old_snap" "$new_snap"
|
|
zfs diff -H "$old_snap" "$new_snap" | grep '^R' | grep -F -- "$prefix" | while read -r diffline
|
|
do
|
|
get_path() {
|
|
path="$(echo -e "$(echo "$diffline" | cut -d$'\t' "-f$1")")"
|
|
echo "${path/#$prefix/$root}"
|
|
}
|
|
|
|
from="$(get_path 2)"
|
|
to="$(get_path 3)"
|
|
debug "From: $from"
|
|
debug "To: $to"
|
|
debug mv '"'"$from"'"' '"'"$to"'"'
|
|
mkdir -vp -- "$(dirname "$to")"
|
|
if [ -e "$to" ] && [ "$clobber" != "--force" ]
|
|
then
|
|
echo "File exists, not clobbering: $to"
|
|
fi
|
|
mv -v "$clobber" -- "$from" "$to" || echo "Unable to move $from"
|
|
done
|
|
|