-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbackup_appdata.sh
executable file
·152 lines (133 loc) · 4 KB
/
backup_appdata.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#!/usr/bin/env bash
set -e -u
set -o pipefail
# `rundroid backup_appdata.sh --all` will auto-backup all apps to $BACKUPDIR located on sdcard
# `rundroid backup_appdata.sh --array` will auto-backup all apps in "${APPS}" defined below
# `rundroid backup_appdata.sh --user 10 com.Slack` will backup just slack appdata for user 10
readonly BACKUPDIR="Documents/oandbackups"
readonly APPS=(
0/com.whatsapp
10/com.Slack
com.aurora.warden
)
function usage ()
{
cat << EOF
Usage: ${0##*/} [OPTION]... [PACKAGE]
BACKUPDIR=${BACKUPDIR}
Options: -h, --help: show this help dialog
-u USER, --user USER: 0 (personal) or 10 (work profile)
--all: backup appdata for all apps
--array: backup appdata for apps listed in APPS array
EOF
}
function backup_appdata ()
{
local user="${1}"; shift
local app_name="${1}"; shift
local backupdir="${1}"; shift
local datadir
local app_dir
local archive_file
cd "/data/user/${user}/"
datadir="/data/user/${user}"
app_dir="${datadir}/${app_name}"
archive_file="${backupdir}/${app_name}/data_$(date +"%Y-%m-%d-%H:%M:%S").tar.gz"
mkdir -p "$(dirname "${archive_file}")"
if [ -d "${app_dir}" ]; then
echo "BACKING UP APPDATA FOR ${app_name}"
tar --exclude cache -C "${app_dir}" -Jcf "${archive_file}" .
else
echo "appdir ${app_dir} fail"
fi
}
function backup_array_appdata ()
{
user="${1}"; shift
backupdir="${1}"; shift
for app in "${APPS[@]}"; do
app_user="$(test -z "${app%%/*}" && echo "${user}" || echo "${app%%/*}")"
app_name="${app##*/}"
backup_appdata "${app_user}" "${app_name}" "/storage/emulated/${app_user}/${backupdir}"
done
}
function backup_all_appdata ()
{
user="${1}"; shift
backupdir="${1}"; shift
for app in $(pm list packages --user "${user}"|sed 's/^package://'); do
backup_appdata "${user}" "${app_name}" "/storage/emulated/${user}/${backupdir}"
done
}
function android_users ()
{
adb shell pm list users|awk 'match($0, /^\s*UserInfo\{([0-9]+):.*:[0-9]+}/, arr) {print arr[1]}'
}
function main ()
{
local user=0
local enable_all=false
local enable_array=false
while getopts "hu-:" opt; do
case ${opt} in
h) # help message
usage
exit 0
;;
u)
user="${!OPTIND}"
OPTIND=$(( OPTIND + 1 ))
;;
-)
case "${OPTARG}" in
help)
usage
exit 0
;;
user)
user="${!OPTIND}"
OPTIND=$(( OPTIND + 1 ))
;;
all)
enable_all=true
;;
array)
enable_array=true
;;
*)
printf 'Unknown option, exiting now\n' >&2
exit 1
;;
esac
;;
?)
printf 'Unknown option, exiting now\n' >&2
exit 1
;;
esac
done
shift $((OPTIND - 1))
[[ "${1:-}" == '--' ]] && shift
if "${enable_all}" && "${enable_array}"; then
printf "Error: cannot pass both --array and --all to script\n" >&2
exit 1
fi
if [ "$#" -ge 1 ]; then
while [ $# -ge 1 ]; do
app="${1}"; shift
backup_appdata "${user}" "${app}"
done
elif "${enable_all}"; then
for u in $(android_users); do
backup_all_appdata "${u}" "${BACKUPDIR}"
done
elif "${enable_array}"; then
backup_array_appdata "${user}" "${BACKUPDIR}"
else
# shellcheck disable=SC2016
printf 'must pass in `--all` flag or specify individual package names\n' >&2
fi
}
if [ "${BASH_SOURCE[0]}" == "$0" ]; then
main "$@"
fi