Skip to content

Instantly share code, notes, and snippets.

@larsenglund
Created April 30, 2025 11:14
Show Gist options
  • Save larsenglund/8fd4dec167d7dc56bc2abedacd7e02e7 to your computer and use it in GitHub Desktop.
Save larsenglund/8fd4dec167d7dc56bc2abedacd7e02e7 to your computer and use it in GitHub Desktop.
#!/bin/bash
# adapted from https://android.stackexchange.com/a/192059/356802
# run as: ./filename.sh <source_folder> <destination_folder>
# if no <destination_folder> is provided, it's stored in current directory.
# Backup
# ./adb-pull.sh -f -v /data data
# Restore
# adb push -a data/ /
usage() {
echo "Usage: $0 <source_folder> <destination_folder>"
echo "Options:"
echo " -v, --verbose Print verbose output"
echo " -f, --force Overwrite files if they already exist"
exit 0
}
echo_verbose() {
if $verbose; then
echo "$1"
fi
}
verbose=false
force=false
POSITIONAL=()
while (( $# > 0 )); do
case "${1}" in
-h|--help)
usage
;;
-v|--verbose)
verbose=true
shift
;;
-f|--force)
force=true
shift
;;
*)
POSITIONAL+=("$1")
shift
;;
esac
done
set -- "${POSITIONAL[@]}" # restore positional params
location=$1
destination=${2:-.}
# find the full path of all the files in the given directory, and retrieve each file one by one
while read -r line; do
echo_verbose "$line" # | od -c
#trimmed="$(echo "$line" | sed $'s/\r$//' | xargs)"
trimmed="$(echo "$line" | tr -d '\r\n' | xargs)"
#echo "$trimmed" | od -c
dst_line=${trimmed#"$location"}
# ignore files with certain patterns
ignore_patterns=("cache") # space separated list of quoted patterns to ignore
for pattern in "${ignore_patterns[@]}"; do
if [[ "${trimmed}" == *"${pattern}"* ]]; then
echo_verbose "Ignoring '${destination}${dst_line}': contains ignored pattern '${pattern}'"
continue 2
fi
done
# create the directory where the file will reside, by removing the filename alone from the fullpath.
# thanks to https://stackoverflow.com/a/9022471/5002496
#echo_verbose "mkdir: ${destination}""${dst_line%/*}"
mkdir -p "${destination}""${dst_line%/*}"
# do not overwrite files that are already present, unless forced
if [ -f "${destination}${dst_line}" ] && ! $force; then
echo_verbose "Skipping ${destination}${dst_line}: already present"
continue
fi
#echo "_pull $trimmed"
#echo "to ${destination}${dst_line} a"
adb pull -a "$trimmed" "${destination}${dst_line}"
echo_verbose "location $location"
done <<< "$(adb shell find "$location" -type f)"
# the find binary in Android doesn't seem to show symlinks when '-type f' option is used.
# source: https://stackoverflow.com/a/16303559/5002496
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment