Skip to content

Instantly share code, notes, and snippets.

@ProBackup-nl
Last active June 5, 2023 17:43
Show Gist options
  • Save ProBackup-nl/13dab09a4f62bb410d5a3895359ee72c to your computer and use it in GitHub Desktop.
Save ProBackup-nl/13dab09a4f62bb410d5a3895359ee72c to your computer and use it in GitHub Desktop.
ddrescue on a directory recursively (using find) skipping existing equally sized targets preservering metadata
#!/bin/bash
# ddrescue on a directory recursively (using find)
# skipping existing equally sized targets
# preservering metadata
# inspired by the-mikedavis ddrfind.fish
if [ -z $1 ] || [ ! -d $1 ] || [ -z $2 ] || [ ! -d $2 ]; then
echo "Usage: ddrfind.sh <input-dir> <output-dir-that-exists>"
echo "Example: ddrfind.sh /Volumes/A/folder-to-rescue /Volumes/B"
exit 1
fi
#sdir=${1##*/}
#echo "sdir=$sdir" #f.e. folder-to-rescue
spath=${1%/*}
#spathlen=${#spath}
#echo "spath=$spath ($spathlen)" #f.e. /Volumes/A
find $1 -print0 | while read -d $'\0' source
do
# strip source path from left side
target=${source#$spath} #f.e. folder-to-rescue/filename.txt
#echo "target=$target"
# source is directory
if [ -d $source ]; then
if [ ! -e "$2$target" ]; then
echo "mkdir $2$target"
#mkdir -p "$2$target"
fi
# source is file
else
# target does not exist
#if [ ! -e "$2$target" ]; then
# or size is different
if [ ! -e "$2$target" ] || [ $(du -k "$source" | cut -f1) != $(du -k "$2$target" | cut -f1) ]; then
echo "rescueing $source $2$target"
#sudo ddrescue -T 1 "$source" "$2$target" #forward
sudo ddrescue -R -T 1 "$source" "$2$target" #reverse
# stop on file io errors
if [ $? -eq 1 ]; then
exit $?
fi
# copy metadata
sudo touch -r "$source" "$2$target"
fi
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment