849 lines
41 KiB
Bash
849 lines
41 KiB
Bash
#!/system/bin/sh
|
||
# module: backup_core.sh
|
||
|
||
backup_path() {
|
||
if [[ $Output_path != "" ]]; then
|
||
[[ ${Output_path: -1} = / ]] && Output_path="${Output_path%?}"
|
||
if [[ ${Output_path:0:1} != / ]]; then
|
||
Directory_type="相對路徑"
|
||
Backup="$MODDIR/$Output_path/Backup_${Compression_method}_$user"
|
||
else
|
||
Directory_type="絕對路徑"
|
||
Backup="$Output_path/Backup_${Compression_method}_$user"
|
||
fi
|
||
outshow="使用自定義目錄($Directory_type)"
|
||
else
|
||
Backup="$MODDIR/Backup_${Compression_method}_$user"
|
||
if [[ ! -f ${0%/*}/app_details.json ]]; then
|
||
outshow="使用當前路徑作為備份目錄"
|
||
else
|
||
[[ -d $Backup ]] && outshow="使用上層路徑作為備份目錄" || echoRgb "$Backup目錄不存在" "0"
|
||
fi
|
||
fi
|
||
PU=$(mount | awk '$3 ~ "/mnt/media_rw/[^/]+$" {print $3, $5}' | egrep -v "$mount_point")
|
||
OTGPATH="$(echo "$PU" | cut -d' ' -f1)"
|
||
OTGFormat="$(echo "$PU" | cut -d' ' -f2)"
|
||
if [[ -d $OTGPATH ]]; then
|
||
if [[ $(echo "$MODDIR" | egrep -o "^${OTGPATH}") != "" ]]; then
|
||
hx="true"
|
||
Backup="$MODDIR/Backup_${Compression_method}_$user"
|
||
else
|
||
case $Lo in
|
||
0|1)
|
||
echoRgb "檢測到隨身碟 是否在隨身碟備份\n -音量上是,音量下不是" "2"
|
||
get_version "選擇了隨身碟備份" "選擇了本地備份" ;;
|
||
2)
|
||
Enter_options "檢測到隨身碟,輸入1使用隨身碟備份 0本地備份" "選擇了隨身碟備份" "本地備份" && isBoolean "$parameter" "branch" && branch="$nsx" ;;
|
||
esac
|
||
[[ $branch = true ]] && hx="$branch"
|
||
[[ $hx = true ]] && Backup="$OTGPATH/Backup_${Compression_method}_$user"
|
||
fi
|
||
if [[ $hx = true ]]; then
|
||
if [[ $OTGFormat = vfat ]]; then
|
||
echoRgb "隨身碟檔案系統$OTGFormat不支持超過單檔4GB\n -請格式化為exfat" "0"
|
||
exit 1
|
||
fi
|
||
outshow="於隨身碟備份" && hx=usb
|
||
fi
|
||
fi
|
||
[[ ! -d $Backup ]] && mkdir -p "$Backup"
|
||
#分區詳細
|
||
if [[ $(echo "$Backup" | egrep -o "^/storage/emulated") != "" ]]; then
|
||
Backup_path="/data"
|
||
else
|
||
Backup_path="${Backup%/*}"
|
||
fi
|
||
echoRgb "$hx備份資料夾所使用分區統計如下↓\n -$(df -h "${Backup%/*}" | sed -n 's|% /.*|%|p' | awk '{print $(NF-3),$(NF-2),$(NF-1),$(NF)}' | awk 'END{print "總共:"$1"已用:"$2"剩餘:"$3"使用率:"$4}')檔案系統:$(df -T "$Backup_path" | sed -n 's|% /.*|%|p' | awk '{print $(NF-4)}')\n -備份目錄輸出位置↓\n -$Backup"
|
||
echoRgb "$outshow" "2"
|
||
}
|
||
Calculate_size() {
|
||
#計算出備份大小跟差異性
|
||
filesizee="$(find "$1" -type f -printf "%s\n" | awk '{s+=$1} END {print s}')"
|
||
if [[ $(echo "$filesizee > $filesize" | bc) -eq 1 ]]; then
|
||
NJL="本次備份增加 $(size "$(echo "scale=2; $filesizee - $filesize" | bc)")"
|
||
elif [[ $(echo "$filesizee < $filesize" | bc) -eq 1 ]]; then
|
||
NJL="本次備份減少 $(size "$(echo "scale=2; $filesize - $filesizee" | bc)")"
|
||
else
|
||
NJL="文件大小未改變"
|
||
fi
|
||
echoRgb "備份資料夾路徑↓↓↓\n -$1"
|
||
echoRgb "備份資料夾總體大小$(size "$filesizee")"
|
||
echoRgb "$NJL"
|
||
}
|
||
Backup_apk() {
|
||
#檢測apk狀態進行備份
|
||
#創建APP備份文件夾
|
||
[[ ! -d $Backup_folder ]] && mkdir -p "$Backup_folder"
|
||
[[ ! -f $app_details ]] && echo "{\n}">"$app_details"
|
||
apk_version="$(jq -r '.[] | select(.apk_version != null).apk_version' "$app_details")"
|
||
apk_version2="$(pm list packages --show-versioncode --user "$user" "$name2" 2>/dev/null | cut -f3 -d ':' | head -n 1)"
|
||
if [[ $apk_version = $apk_version2 ]]; then
|
||
[[ $(echo "$txt2" | sed -e '/^$/d' | cut -d' ' -f2 | awk -v pkg="$name2" '$1 == pkg {print $1}') = "" ]] && txt2="$txt2\n${Backup_folder##*/} $name2"
|
||
unset xb
|
||
osj=$((osj + 1))
|
||
result=0
|
||
echoRgb "Apk版本無更新 跳過備份" "2"
|
||
else
|
||
if [[ $nobackup = false ]]; then
|
||
if [[ $apk_version != "" ]]; then
|
||
osn=$((osn + 1))
|
||
update_apk="$(echo "$name1 \"$name2\"")"
|
||
update_apk2="$(echo "$update_apk\n$update_apk2")"
|
||
echoRgb "版本:$apk_version>$apk_version2"
|
||
else
|
||
osk=$((osk + 1))
|
||
add_app="$(echo "$name1 \"$name2\"")"
|
||
add_app2="$(echo "$add_app\n$add_app2")"
|
||
echoRgb "版本:$apk_version2"
|
||
fi
|
||
unset Filesize
|
||
Filesize="$(find "$apk_path2" -type f -printf "%s\n" | awk '{s+=$1} END {print s}')"
|
||
rm -rf "$Backup_folder/apk.tar"*
|
||
partition_info "$Backup" "$name1 apk"
|
||
if [[ $Skip != 1 ]]; then
|
||
#備份apk
|
||
echoRgb "$1"
|
||
echo "$apk_path" | sed -e '/^$/d' | while read; do
|
||
echoRgb "${REPLY##*/} $(size "$REPLY")"
|
||
done
|
||
(
|
||
cd "$apk_path2"
|
||
case $Compression_method in
|
||
tar | TAR | Tar) tar --checkpoint-action="ttyout=%T\r" -cf "$Backup_folder/apk.tar" *.apk ;;
|
||
zstd | Zstd | ZSTD) tar --checkpoint-action="ttyout=%T\r" -cf - *.apk | zstd --ultra -3 -T0 -q --priority=rt >"$Backup_folder/apk.tar.zst" ;;
|
||
esac
|
||
)
|
||
echo_log "備份$apk_number個Apk"
|
||
if [[ $result = 0 ]]; then
|
||
Validation_file "$Backup_folder/apk.tar"*
|
||
if [[ $result = 0 ]]; then
|
||
[[ $(echo "$txt2" | sed -e '/^$/d' | cut -d' ' -f2 | awk -v pkg="$name2" '$1 == pkg {print $1}') = "" ]] && txt2="$txt2\n${Backup_folder##*/} $name2"
|
||
[[ $apk_version != "" ]] && {
|
||
echoRgb "覆蓋app_details"
|
||
jq --arg apk_version "$apk_version2" --arg software "$name1" '.[$software].apk_version = $apk_version' "$app_details" > "$TMPDIR/temp.json" && mv "$TMPDIR/temp.json" "$app_details"
|
||
} || {
|
||
echoRgb "新增app_details"
|
||
extra_content="{
|
||
\"$name1\": {
|
||
\"PackageName\": \"$name2\",
|
||
\"apk_version\": \"$apk_version2\"
|
||
}
|
||
}"
|
||
jq --argjson new_content "$extra_content" '. += $new_content' "$app_details" > "$TMPDIR/temp.json" && mv "$TMPDIR/temp.json" "$app_details"
|
||
}
|
||
else
|
||
rm -rf "$Backup_folder"
|
||
fi
|
||
if [[ $name2 = com.android.chrome ]]; then
|
||
#刪除所有舊apk ,保留一個最新apk進行備份
|
||
ReservedNum=1
|
||
FileNum="$(ls /data/app/*/com.google.android.trichromelibrary_*/base.apk 2>/dev/null | wc -l)"
|
||
while [[ $FileNum -gt $ReservedNum ]]; do
|
||
OldFile="$(ls -rt /data/app/*/com.google.android.trichromelibrary_*/base.apk 2>/dev/null | head -1)"
|
||
rm -rf "${OldFile%/*/*}" && echo "刪除文件:${OldFile%/*/*}"
|
||
FileNum=$((FileNum - 1))
|
||
done
|
||
[[ -f $(ls /data/app/*/com.google.android.trichromelibrary_*/base.apk 2>/dev/null) && $(ls /data/app/*/com.google.android.trichromelibrary_*/base.apk 2>/dev/null | wc -l) = 1 ]] && cp -r "$(ls /data/app/*/com.google.android.trichromelibrary_*/base.apk 2>/dev/null)" "$Backup_folder/nmsl.apk"
|
||
fi
|
||
else
|
||
rm -rf "$Backup_folder"
|
||
fi
|
||
fi
|
||
else
|
||
osj=$((osj + 1))
|
||
rm -rf "$Backup_folder"
|
||
fi
|
||
fi
|
||
[[ $name2 = bin.mt.plus && ! -f $Backup/$name1.apk ]] && cp -r "$apk_path" "$Backup/$name1.apk"
|
||
}
|
||
Backup_ssaid() {
|
||
Ssaid="$(jq -r '.[] | select(.Ssaid != null).Ssaid' "$app_details")"
|
||
ssaid="$(awk -v pkg="$name2" '$1 == pkg {print $2}'<<<"$ssaid_info")"
|
||
[[ $ssaid != null && $ssaid != "" ]] && echoRgb "SSAID:$ssaid"
|
||
if [[ $ssaid != null && $ssaid != $Ssaid ]]; then
|
||
echoRgb "備份ssaid"
|
||
echoRgb "$Ssaid>$ssaid"
|
||
SSAID_apk="$(echo "$name1 \"$name2\"")"
|
||
SSAID_apk2="$(echo "$SSAID_apk\n$SSAID_apk2")"
|
||
jq --arg entry "$name1" --arg new_value "$ssaid" '.[$entry].Ssaid |= $new_value' "$app_details" > "$TMPDIR/temp.json" && mv "$TMPDIR/temp.json" "$app_details"
|
||
echo_log "備份ssaid"
|
||
fi
|
||
[[ $ssaid = null ]] && ssaid=
|
||
}
|
||
Backup_Permissions() {
|
||
get_Permissions="$(jq -r '.[] | select(.permissions != null).permissions' "$app_details")"
|
||
Get_Permissions="$(get_Permissions "$name2" | jq -nR '[inputs | select(. != "null" and length>0) | split(" ") | {(.[0]): (.[1:] | join(" "))}] | if length > 0 then add else empty end')"
|
||
if [[ $Get_Permissions != "" && ($Get_Permissions = *true* || $Get_Permissions = *false*) ]]; then
|
||
if [[ $get_Permissions = "" ]]; then
|
||
echoRgb "備份權限"
|
||
jq --arg packageName "$name1" --argjson permissions "$Get_Permissions" '.[$packageName].permissions |= $permissions' "$app_details" > "$TMPDIR/temp.json" && mv "$TMPDIR/temp.json" "$app_details"
|
||
echo_log "備份權限"
|
||
else
|
||
if [[ $get_Permissions != "" && ($get_Permissions = *true* || $get_Permissions = *false*) ]]; then
|
||
if [[ $get_Permissions != $Get_Permissions ]]; then
|
||
echoRgb "權限變更"
|
||
jq -n --argjson old "$get_Permissions" --argjson new "$Get_Permissions" '$new | to_entries | map(select(.key as $k | $old[$k] != null and $old[$k] != .value)) | .[].key' | sed 's/^/ /'
|
||
jq --arg packageName "$name1" --argjson permissions "$Get_Permissions" '.[$packageName] |= . + {permissions: $permissions}' "$app_details" > "$TMPDIR/temp.json" && mv "$TMPDIR/temp.json" "$app_details"
|
||
echo_log "備份權限"
|
||
fi
|
||
fi
|
||
fi
|
||
else
|
||
[[ $Get_Permissions != "" ]] && echoRgb "備份權限失敗$(get_Permissions "$name2")" "0"
|
||
fi
|
||
}
|
||
#檢測數據位置進行備份
|
||
Backup_data() {
|
||
data_path="$path/$1/$name2"
|
||
MODDIR_NAME="${data_path%/*}"
|
||
MODDIR_NAME="${MODDIR_NAME##*/}"
|
||
[[ -f $app_details ]] && Size="$(jq -r --arg entry "$1" '.[$entry] | select(.Size != null).Size' "$app_details" 2>/dev/null)"
|
||
case $1 in
|
||
user) data_path="$path2/$name2" ;;
|
||
user_de) data_path="$path3/$name2" ;;
|
||
data|obb) ;;
|
||
*)
|
||
data_path="$2"
|
||
if [[ $1 != thanox ]]; then
|
||
Compression_method1="$Compression_method"
|
||
Compression_method=tar
|
||
fi
|
||
zsize=1
|
||
zmediapath=1
|
||
;;
|
||
esac
|
||
if [[ -d $data_path ]]; then
|
||
unset Filesize ssaid Get_Permissions result Permissions
|
||
Filesize="$(find "$data_path" -type f -printf "%s\n" 2>/dev/null | awk '{s+=$1} END {print s}')"
|
||
[[ $Filesize != "" ]] && {
|
||
if [[ $Size != $Filesize ]]; then
|
||
case $1 in
|
||
user)
|
||
if [[ $(su "$(pm list packages -U --user "$user" </dev/null | awk -v pkg="$name2" -F'[ :]' '$2 == pkg {print $4}')" -c keystore_cli_v2 list | wc -l) -ge 2 ]]; then
|
||
echoRgb "$name1包含keystore 恢復可能閃退" "0"
|
||
jq --arg entry "$name1" '.[$entry].keystore |= "true"' "$app_details" > "$TMPDIR/temp.json" && mv "$TMPDIR/temp.json" "$app_details"
|
||
else
|
||
jq --arg entry "$name1" '.[$entry].keystore |= "false"' "$app_details" > "$TMPDIR/temp.json" && mv "$TMPDIR/temp.json" "$app_details"
|
||
fi
|
||
Backup_ssaid
|
||
Backup_Permissions ;;
|
||
esac
|
||
#停止應用
|
||
case $1 in
|
||
user|data|obb|user_de) kill_app ;;
|
||
esac
|
||
rm -rf "$Backup_folder/$1.tar"*
|
||
partition_info "$Backup" "$1"
|
||
if [[ $Skip != 1 ]]; then
|
||
echoRgb "備份$1數據"
|
||
# 判斷是否超過指定大小
|
||
if [[ $Filesize2 != *"bytes"* ]]; then
|
||
if [[ $Filesize2 = *"KB"* ]]; then
|
||
if [[ $(echo "${Filesize2% KB}" | bc) > 1 ]]; then
|
||
Start_backup="true"
|
||
else
|
||
Start_backup="false"
|
||
fi
|
||
else
|
||
Start_backup="true"
|
||
fi
|
||
else
|
||
Start_backup="false"
|
||
fi
|
||
if [[ $Start_backup = true ]]; then
|
||
case $1 in
|
||
user|user_de)
|
||
case $Compression_method in
|
||
tar | Tar | TAR) tar --checkpoint-action="ttyout=%T\r" --exclude="${data_path##*/}/.ota" --exclude="${data_path##*/}/cache" --exclude="${data_path##*/}/lib" --exclude="${data_path##*/}/code_cache" --exclude="${data_path##*/}/no_backup" --warning=no-file-changed -cpf "$Backup_folder/$1.tar" -C "${data_path%/*}" "${data_path##*/}" 2>/dev/null ;;
|
||
zstd | Zstd | ZSTD) tar --checkpoint-action="ttyout=%T\r" --exclude="${data_path##*/}/.ota" --exclude="${data_path##*/}/cache" --exclude="${data_path##*/}/lib" --exclude="${data_path##*/}/code_cache" --exclude="${data_path##*/}/no_backup" --warning=no-file-changed -cpf - -C "${data_path%/*}" "${data_path##*/}" | zstd --ultra -3 -T0 -q --priority=rt >"$Backup_folder/$1.tar.zst" 2>/dev/null ;;
|
||
esac
|
||
;;
|
||
*)
|
||
case $Compression_method in
|
||
tar | Tar | TAR) tar --checkpoint-action="ttyout=%T\r" --exclude="Backup_"* --exclude="${data_path##*/}/cache" --exclude="${data_path##*/}/QQ" --exclude="${data_path##*/}/Telegram" --exclude="${data_path##*/}"/.* --warning=no-file-changed -cpf "$Backup_folder/$1.tar" -C "${data_path%/*}" "${data_path##*/}" ;;
|
||
zstd | Zstd | ZSTD) tar --checkpoint-action="ttyout=%T\r" --exclude="Backup_"* --exclude="${data_path##*/}/cache" --exclude="${data_path##*/}/QQ" --exclude="${data_path##*/}/Telegram" --exclude="${data_path##*/}"/.* --warning=no-file-changed -cpf - -C "${data_path%/*}" "${data_path##*/}" | zstd --ultra -3 -T0 -q --priority=rt >"$Backup_folder/$1.tar.zst" ;;
|
||
esac
|
||
;;
|
||
esac
|
||
echo_log "備份$1數據"
|
||
else
|
||
echoRgb "$1數據 $Filesize2太小" "0" && result=1
|
||
fi
|
||
if [[ $result = 0 ]]; then
|
||
Validation_file "$Backup_folder/$1.tar"*
|
||
if [[ $result = 0 ]]; then
|
||
if [[ ! $Filesize -eq 0 ]]; then
|
||
size2="$(stat -c %s "$Backup_folder/$1.tar"*)"
|
||
rate="$(echo "scale=2; (1 - ($size2 / $Filesize)) * 100" | bc)"
|
||
echoRgb "壓縮率${rate}% 大小$(size "$size2")"
|
||
fi
|
||
[[ ${Backup_folder##*/} = Media ]] && [[ $(sed -e '/^$/d' "$mediatxt" | grep -w "${REPLY##*/}.tar$" | head -1) = "" ]] && echo "$FILE_NAME" >> "$mediatxt"
|
||
if [[ $zsize != "" ]]; then
|
||
extra_content="{
|
||
\"$1\": {
|
||
\"path\": \"$2\",
|
||
\"Size\": \"$Filesize\"
|
||
},
|
||
\"Backup time\": {
|
||
\"date\": \"$(date "+%Y.%m.%d %H:%M:%S")\"
|
||
}
|
||
}"
|
||
jq --argjson new_content "$extra_content" '. += $new_content' "$app_details" > "$TMPDIR/temp.json" && mv "$TMPDIR/temp.json" "$app_details"
|
||
else
|
||
extra_content="{
|
||
\"$1\": {
|
||
\"Size\": \"$Filesize\"
|
||
},
|
||
\"Backup time\": {
|
||
\"date\": \"$(date "+%Y.%m.%d %H:%M:%S")\"
|
||
}
|
||
}"
|
||
jq --argjson new_content "$extra_content" '. += $new_content' "$app_details" > "$TMPDIR/temp.json" && mv "$TMPDIR/temp.json" "$app_details"
|
||
fi
|
||
else
|
||
rm -rf "$Backup_folder/$1".tar.*
|
||
fi
|
||
fi
|
||
[[ $Compression_method1 != "" ]] && Compression_method="$Compression_method1"
|
||
unset Compression_method1
|
||
fi
|
||
else
|
||
[[ $Size != "" ]] && echoRgb "$1數據無發生變化 跳過備份" "2"
|
||
fi
|
||
}
|
||
else
|
||
[[ -f $data_path ]] && echoRgb "$1是一個文件 不支持備份" "0"
|
||
fi
|
||
}
|
||
# ===================== 子函數: 驗證備份參數 =====================
|
||
validate_backup_params() {
|
||
self_test
|
||
case $MODDIR in
|
||
/storage/emulated/0/Android/* | /data/media/0/Android/* | /sdcard/Android/*) echoRgb "請勿在$MODDIR內備份" "0" && exit 2 ;;
|
||
esac
|
||
case $Compression_method in
|
||
zstd | Zstd | ZSTD | tar | Tar | TAR) ;;
|
||
*) echoRgb "$Compression_method為不支持的壓縮算法" "0" && exit 2 ;;
|
||
esac
|
||
#校驗選填是否正確
|
||
case $Lo in
|
||
0)
|
||
[[ $Backup_Mode != "" ]] && isBoolean "$Backup_Mode" "Backup_Mode" && Backup_Mode="$nsx" || {
|
||
echoRgb "選擇備份模式\n -音量上備份應用+數據,音量下僅應用不包含數據" "2"
|
||
get_version "應用+數據" "僅應用" && Backup_Mode="$branch"
|
||
}
|
||
if [[ $Backup_Mode = true ]]; then
|
||
if [[ $(echo "$blacklist" | egrep -v '#|#' | wc -l) -gt 0 ]]; then
|
||
if [[ $blacklist_mode != "" ]]; then
|
||
isBoolean "$blacklist_mode" "blacklist_mode" && blacklist_mode="$nsx"
|
||
else
|
||
echoRgb "選擇黑名單模式\n -音量上不備份,音量下僅備份安裝檔\n -警告! " "2"
|
||
get_version "不備份" "備份安裝檔" && blacklist_mode="$branch"
|
||
fi
|
||
fi
|
||
fi
|
||
if [[ $Backup_Mode = true ]]; then
|
||
[[ $Backup_obb_data != "" ]] && isBoolean "$Backup_obb_data" "Backup_obb_data" && Backup_obb_data="$nsx" || {
|
||
echoRgb "是否備份外部數據 即比如原神的數據包\n -音量上備份,音量下不備份" "2"
|
||
get_version "備份" "不備份" && Backup_obb_data="$branch"
|
||
}
|
||
[[ $Backup_user_data != "" ]] && isBoolean "$Backup_user_data" "Backup_user_data" && Backup_user_data="$nsx" || {
|
||
echoRgb "是否備份使用者數據\n -音量上備份,音量下不備份" "2"
|
||
get_version "備份" "不備份" && Backup_user_data="$branch"
|
||
}
|
||
else
|
||
Backup_user_data="false"
|
||
Backup_obb_data="false"
|
||
fi
|
||
[[ $backup_media != "" ]] && isBoolean "$backup_media" "backup_media" && backup_media="$nsx" || {
|
||
echoRgb "全部應用備份結束後是否備份自定義目錄\n -音量上備份,音量下不備份" "2"
|
||
get_version "備份" "不備份" && backup_media="$branch"
|
||
}
|
||
[[ $setDisplayPowerMode != "" ]] && isBoolean "$setDisplayPowerMode" "setDisplayPowerMode" && setDisplayPowerMode="$nsx" || {
|
||
echoRgb "應用備份開始後關閉螢幕\n -音量上關閉,音量下不關閉" "2"
|
||
get_version "關閉" "不關閉" && setDisplayPowerMode="$branch"
|
||
}
|
||
[[ $Background_apps_ignore != "" ]] && isBoolean "$Background_apps_ignore" "Background_apps_ignore" && Background_apps_ignore="$nsx" || {
|
||
echoRgb "存在進程忽略備份\n -音量上忽略,音量下備份" "2"
|
||
get_version "忽略" "備份" && Background_apps_ignore="$branch"
|
||
} ;;
|
||
1)
|
||
[[ $Backup_Mode = "" ]] && {
|
||
echoRgb "選擇備份模式\n -音量上備份應用+數據,音量下僅應用不包含數據" "2"
|
||
get_version "應用+數據" "僅應用" && Backup_Mode="$branch"
|
||
} || isBoolean "$Backup_Mode" "Backup_Mode" && Backup_Mode="$nsx"
|
||
if [[ $Backup_Mode = true ]]; then
|
||
if [[ $(echo "$blacklist" | egrep -v '#|#' | wc -l) -gt 0 ]]; then
|
||
[[ $blacklist_mode = "" ]] && {
|
||
echoRgb "選擇黑名單模式\n -音量上不備份,音量下僅備份安裝檔" "2"
|
||
get_version "不備份" "備份安裝檔" && blacklist_mode="$branch"
|
||
} || isBoolean "$blacklist_mode" "blacklist_mode" && blacklist_mode="$nsx"
|
||
fi
|
||
[[ $Backup_obb_data = "" ]] && {
|
||
echoRgb "是否備份外部數據 即比如原神的數據包\n -音量上備份,音量下不備份" "2"
|
||
get_version "備份" "不備份" && Backup_obb_data="$branch"
|
||
} || isBoolean "$Backup_obb_data" "Backup_obb_data" && Backup_obb_data="$nsx"
|
||
[[ $Backup_user_data = "" ]] && {
|
||
echoRgb "是否備份使用者數據\n -音量上備份,音量下不備份" "2"
|
||
get_version "備份" "不備份" && Backup_user_data="$branch"
|
||
} || isBoolean "$Backup_user_data" "Backup_user_data" && Backup_user_data="$nsx"
|
||
fi
|
||
[[ $backup_media = "" ]] && {
|
||
echoRgb "全部應用備份結束後是否備份自定義目錄\n -音量上備份,音量下不備份" "2"
|
||
get_version "備份" "不備份" && backup_media="$branch"
|
||
} || isBoolean "$backup_media" "backup_media" && backup_media="$nsx"
|
||
[[ $setDisplayPowerMode = "" ]] && {
|
||
echoRgb "應用備份開始後關閉螢幕\n -音量上關閉,音量下不關閉" "2"
|
||
get_version "關閉" "不關閉" && setDisplayPowerMode="$branch"
|
||
} || isBoolean "$setDisplayPowerMode" "setDisplayPowerMode" && setDisplayPowerMode="$nsx"
|
||
[[ $Background_apps_ignore = "" ]] && {
|
||
echoRgb "存在進程忽略備份\n -音量上忽略,音量下備份" "2"
|
||
get_version "忽略" "備份" && Background_apps_ignore="$branch"
|
||
} || isBoolean "$Background_apps_ignore" "Background_apps_ignore" && Background_apps_ignore="$nsx"
|
||
;;
|
||
2)
|
||
[[ $Backup_Mode = "" ]] && {
|
||
Enter_options "輸入1備份應用+數據,輸入0僅應用不包含數據" "應用+數據" "僅應用" && isBoolean "$parameter" "Backup_Mode" && Backup_Mode="$nsx"
|
||
} || {
|
||
isBoolean "$Backup_Mode" "Backup_Mode" && Backup_Mode="$nsx"
|
||
}
|
||
if [[ $Backup_Mode = true ]]; then
|
||
[[ $(echo "$blacklist" | egrep -v '#|#' | wc -l) -gt 0 ]] && {
|
||
[[ $blacklist_mode = "" ]] && {
|
||
Enter_options "選擇黑名單模式輸入1不備份,輸入0備份安裝檔" "不備份" "僅應用安裝檔" && isBoolean "$parameter" "blacklist_mode" && blacklist_mode="$nsx"
|
||
} || {
|
||
isBoolean "$blacklist_mode" "blacklist_mode" && blacklist_mode="$nsx"
|
||
}
|
||
}
|
||
[[ $Backup_obb_data = "" ]] && {
|
||
Enter_options "是否備份外部數據 即比如原神的數據包\n -輸入1備份,輸入0不備份" "備份" "不備份" && isBoolean "$parameter" "Backup_obb_data" && Backup_obb_data="$nsx"
|
||
} || {
|
||
isBoolean "$Backup_obb_data" "Backup_obb_data" && Backup_obb_data="$nsx"
|
||
}
|
||
[[ $Backup_user_data = "" ]] && {
|
||
Enter_options "是否備份使用者數據,輸入1備份,輸入0不備份" "備份" "不備份" && isBoolean "$parameter" "Backup_user_data" && Backup_user_data="$nsx"
|
||
} || {
|
||
isBoolean "$Backup_user_data" "Backup_user_data" && Backup_user_data="$nsx"
|
||
}
|
||
fi
|
||
[[ $backup_media = "" ]] && {
|
||
Enter_options "全部應用備份結束後是否備份自定義目錄\n -輸入1備份,0不備份" "備份" "不備份" && isBoolean "$parameter" "backup_media" && backup_media="$nsx"
|
||
} || {
|
||
isBoolean "$backup_media" "backup_media" && backup_media="$nsx"
|
||
}
|
||
[[ $setDisplayPowerMode = "" ]] && {
|
||
Enter_options "應用備份開始後關閉螢幕\n -輸入1關閉,0不關閉" "關閉" "不關閉" && isBoolean "$parameter" "setDisplayPowerMode" && setDisplayPowerMode="$nsx"
|
||
} || {
|
||
isBoolean "$setDisplayPowerMode" "setDisplayPowerMode" && setDisplayPowerMode="$nsx"
|
||
}
|
||
[[ $Background_apps_ignore = "" ]] && {
|
||
Enter_options "存在進程忽略備份\n -輸入1不備份,0備份" "忽略" "備份" && isBoolean "$parameter" "Background_apps_ignore" && Background_apps_ignore="$nsx"
|
||
} || {
|
||
isBoolean "$Background_apps_ignore" "Background_apps_ignore" && Background_apps_ignore="$nsx"
|
||
} ;;
|
||
*) echoRgb "$conf_path Lo=$Lo填寫錯誤,正確值0 1 2" "0" && exit 2 ;;
|
||
esac
|
||
}
|
||
|
||
# ===================== 子函數: 準備應用列表 =====================
|
||
prepare_app_list() {
|
||
i=1
|
||
#數據目錄
|
||
if [[ $list_location != "" ]]; then
|
||
if [[ ${list_location:0:1} = / ]]; then
|
||
txt="$list_location"
|
||
else
|
||
txt="$MODDIR/$list_location"
|
||
fi
|
||
else
|
||
txt="$MODDIR/appList.txt"
|
||
fi
|
||
txt="${txt/'/storage/emulated/'/'/data/media/'}"
|
||
txt_path="$txt"
|
||
[[ ! -f $txt ]] && echoRgb "請執行start.sh獲取應用列表再來備份" "0" && exit 1
|
||
TXT_NAME="${txt##*/}"
|
||
case ${TXT_NAME##*.} in
|
||
txt) ;;
|
||
*) echoRgb "$txt不是腳本讀取格式" "0" && exit 2 ;;
|
||
esac
|
||
sort -u "$txt" -o "$txt" &>/dev/null
|
||
data="$MODDIR"
|
||
hx="本地"
|
||
echoRgb "腳本受到內核機制影響 息屏後IO性能嚴重影響\n -請勿關閉終端或是息屏備份 如需終止腳本\n -請執行start.sh選擇終止腳本即可停止" "3"
|
||
backup_path
|
||
echoRgb "配置詳細:\n -壓縮方式:$Compression_method\n -音量鍵確認:$Lo\n -更新:$update\n -備份模式:$Backup_Mode\n -備份外部數據:$Backup_obb_data\n -備份user數據:$Backup_user_data\n -自定義目錄備份:$backup_media\n -存在進程忽略備份:$Background_apps_ignore\n -關閉螢幕:$setDisplayPowerMode"
|
||
D="1"
|
||
Apk_info="$(pm list packages --user "$user" | cut -f2 -d ':' | egrep -v 'ice.message|com.topjohnwu.magisk' | sort -u)"
|
||
if [[ $Apk_info != "" ]]; then
|
||
[[ $Apk_info = *"Failure calling service package"* ]] && Apk_info="$(appinfo "user|system" "pkgName" 2>/dev/null | egrep -v 'ice.message|com.topjohnwu.magisk' | sort -u)"
|
||
else
|
||
Apk_info="$(appinfo "user|system" "pkgName" 2>/dev/null | egrep -v 'ice.message|com.topjohnwu.magisk' | sort -u)"
|
||
fi
|
||
[[ $Apk_info = "" ]] && echoRgb "Apk_info變量為空" "0" && exit
|
||
[[ ! -f ${0%/*}/app_details.json ]] && {
|
||
echoRgb "檢查備份列表中是否存在已經卸載應用" "3"
|
||
while read -r ; do
|
||
if [[ $(echo "$REPLY" | sed -E 's/^[ \t]*//; /^[ \t]*[##!]/d') != "" ]]; then
|
||
app=($REPLY $REPLY)
|
||
if [[ ${app[1]} != "" && ${app[2]} != "" ]]; then
|
||
if [[ $(echo "$Apk_info" | awk -v pkg="${app[1]}" '$1 == pkg {print $1}') != "" ]]; then
|
||
[[ $Tmplist = "" ]] && Tmplist='#不需要備份的應用請在開頭使用#注釋 比如:#酷安 com.coolapk.market(忽略安裝包和數據)\n#不需要備份數據的應用請在開頭使用!注釋 比如:!酷安 com.coolapk.market(僅忽略數據)'
|
||
Tmplist="$Tmplist\n$REPLY"
|
||
else
|
||
echoRgb "$REPLY不存在系統,從列表中刪除" "0"
|
||
fi
|
||
fi
|
||
else
|
||
Tmplist="$Tmplist\n$REPLY"
|
||
fi
|
||
done < "$txt"
|
||
}
|
||
[[ $Update_backup = true ]] && {
|
||
echoRgb "檢查備份列表中已經更新應用" "3"
|
||
while read apk; do
|
||
Backup_folder="$Backup/$(echo "$apk" | cut -d':' -f1)"
|
||
app_details="$Backup_folder/app_details.json"
|
||
if [[ -d $Backup_folder ]]; then
|
||
apk_version="$(jq -r '.[] | select(.apk_version != null).apk_version' "$app_details")"
|
||
apk_version2="$(pm list packages --show-versioncode --user "$user" "$(echo "$apk" | cut -d':' -f2)" </dev/null | cut -f3 -d ':' | head -n 1)"
|
||
[[ $apk_version != $apk_version2 ]] && {
|
||
[[ $Tmplist2 = "" ]] && Tmplist2="${apk/:/ }" || Tmplist2="$Tmplist2\n${apk/:/ }"
|
||
}
|
||
fi
|
||
done<<<"$(grep -Ev '^[##!]' "$txt" | awk '{print $1 ":" $2}')"
|
||
}
|
||
[[ $Tmplist != "" ]] && echo "$Tmplist" | sed -e '/^$/d' | sort>"$txt"
|
||
if [[ $Tmplist2 != "" ]]; then
|
||
txt="$(echo "$Tmplist2" | sort)"
|
||
else
|
||
[[ $Update_backup != "" ]] && echoRgb "應用目前無更新" "0" && exit 0
|
||
fi
|
||
if [[ ! -f $txt ]]; then
|
||
[[ $(echo "$txt") != "" ]] && txt="$(echo "$txt" | sed -e '/^$/d')"
|
||
else
|
||
txt="$(egrep -v '#|#' "$txt" | sed -e '/^$/d')"
|
||
fi
|
||
r="$(echo "$txt" | awk 'NF != 0 { count++ } END { print count }')"
|
||
[[ -f ${0%/*}/app_details.json ]] && r=1
|
||
[[ $r = "" && ! -f ${0%/*}/app_details.json ]] && echoRgb "$MODDIR_NAME/appList.txt是空的或是包名被注釋備份個鬼\n -檢查是否注釋亦或者執行$MODDIR_NAME/start.sh" "0" && exit 1
|
||
}
|
||
|
||
# ===================== 子函數: 初始化備份存儲 =====================
|
||
init_backup_storage() {
|
||
if [[ $Backup_Mode = true ]]; then
|
||
[[ $Backup_user_data = false ]] && echoRgb "當前$MODDIR_NAME/backup_settings.conf的\n -Backup_user_data=0將不備份user數據" "0"
|
||
[[ $Backup_obb_data = false ]] && echoRgb "當前$MODDIR_NAME/backup_settings.conf的\n -Backup_obb_data=0將不備份外部數據" "0"
|
||
fi
|
||
[[ $backup_media = false ]] && echoRgb "當前$MODDIR_NAME/backup_settings.conf的\n -backup_media=0將不備份自定義資料夾" "0"
|
||
txt2="$Backup/appList.txt"
|
||
txt2="${txt2/'/storage/emulated/'/'/data/media/'}"
|
||
txt_path2="$txt2"
|
||
[[ ! -f $txt2 ]] && echo "#不需要恢復還原的應用請在開頭使用#注釋 比如:#酷安 com.coolapk.market">"$txt2"
|
||
txt2="$(cat "$txt2")"
|
||
[[ ! -d $Backup/tools ]] && cp -r "$tools_path" "$Backup"
|
||
[[ ! -f $Backup/start.sh ]] && touch_shell "2" "$Backup/start.sh"
|
||
[[ ! -f $Backup/restore_settings.conf ]] && update_Restore_settings_conf>"$Backup/restore_settings.conf"
|
||
if [[ -d $Backup/tools ]]; then
|
||
find "$Backup/tools" -maxdepth 1 -type f | while read; do
|
||
Tools_FILE_NAME="${REPLY##*/}"
|
||
if [[ -f $tools_path/$Tools_FILE_NAME ]]; then
|
||
filesha256="$(sha256sum "$tools_path/$Tools_FILE_NAME" 2>/dev/null | cut -d" " -f1)"
|
||
filesha256_1="$(sha256sum "$REPLY" 2>/dev/null | cut -d" " -f1)"
|
||
if [[ $filesha256 != $filesha256_1 ]]; then
|
||
cp -r "$tools_path/$Tools_FILE_NAME" "$REPLY"
|
||
echoRgb "更新$REPLY"
|
||
fi
|
||
fi
|
||
done
|
||
fi
|
||
filesize="$(find "$Backup" -type f -printf "%s\n" | awk '{s+=$1} END {print s}')"
|
||
Quantity=0
|
||
#開始循環$txt內的資料進行備份
|
||
#記錄開始時間
|
||
en=118 # ANSI 256色起始編號,用於通知欄圖標顏色
|
||
osn=0; osj=0; osk=0
|
||
#獲取已經開啟的無障礙
|
||
var="$(settings get secure enabled_accessibility_services 2>/dev/null)"
|
||
#獲取預設鍵盤
|
||
keyboard="$(settings get secure default_input_method 2>/dev/null)"
|
||
Set_screen_pause_seconds on
|
||
[[ $txt != "" ]] && [[ $(echo "$txt" | cut -d' ' -f2 | grep -w "^${keyboard%/*}$") != ${keyboard%/*} ]] && unset keyboard
|
||
if [[ -f ${0%/*}/app_details.json ]]; then
|
||
ssaid_info="$(get_ssaid "$(jq -r '.[] | select(.PackageName != null).PackageName' "${0%/*}/app_details.json")")"
|
||
else
|
||
ssaid_info="$(get_ssaid "$(echo "$txt" | awk '{printf "%s ", $2}')")"
|
||
fi
|
||
starttime1="$(date -u "+%s")"
|
||
TIME="$starttime1"
|
||
notification "101" "開始備份"
|
||
}
|
||
|
||
# ===================== 子函數: 應用循環備份 =====================
|
||
backup_applications_loop() {
|
||
while [[ $i -le $r ]]; do
|
||
[[ $en -ge 229 ]] && en=118 # 超過229重置,避免顏色越界
|
||
unset name1 name2 apk_path apk_path2
|
||
if [[ ! -f ${0%/*}/app_details.json ]]; then
|
||
name1="$(echo "$txt" | sed -n "${i}p" | cut -d' ' -f1)"
|
||
name2="$(echo "$txt" | sed -n "${i}p" | cut -d' ' -f2)"
|
||
else
|
||
ChineseName="$(jq -r 'to_entries[] | select(.key != null).key' "${0%/*}/app_details.json" | head -n 1)"
|
||
PackageName="$(jq -r '.[] | select(.PackageName != null).PackageName' "${0%/*}/app_details.json")"
|
||
name1="$ChineseName"
|
||
name2="$PackageName"
|
||
fi
|
||
[[ $name2 = "" || $name1 = "" ]] && echoRgb "警告! appList.txt應用包名獲取失敗,可能修改有問題" "0" && exit 1
|
||
apk_path="$(pm path --user "$user" "$name2" 2>/dev/null | cut -f2 -d ':')"
|
||
apk_path2="$(echo "$apk_path" | head -1)"
|
||
apk_path2="${apk_path2%/*}"
|
||
if [[ -d $apk_path2 ]]; then
|
||
echoRgb "備份第$i/$r個應用 剩下$((r - i))個" "3"
|
||
echoRgb "備份 $name1" "2"
|
||
notification "101" "備份第$i/$r個應用 剩下$((r - i))個
|
||
備份 $name1"
|
||
unset Backup_folder ChineseName PackageName nobackup No_backupdata result apk_version apk_version2 zsize zmediapath Size data_path Ssaid ssaid Permissions
|
||
nobackup="false"
|
||
Background_application_list
|
||
[[ $Backstage != "" && $(echo "$Backstage" | egrep -w "^$name2$") != "" ]] && echoRgb "$name1存在後台 忽略備份" "0" && nobackup="true"
|
||
if [[ $Backup_Mode = true ]]; then
|
||
if [[ $name1 = !* || $name1 = !* ]]; then
|
||
name1="$(echo "$name1" | sed 's/!//g ; s/!//g')"
|
||
echoRgb "跳過備份所有數據" "0"
|
||
No_backupdata=1
|
||
fi
|
||
if [[ $(echo "$blacklist" | grep -w "^$name2$") = $name2 ]]; then
|
||
if [[ $blacklist_mode = true ]]; then
|
||
echoRgb "黑名單應用跳過備份" "0"
|
||
nobackup="true"
|
||
else
|
||
echoRgb "黑名單應用跳過備份所有數據" "0"
|
||
fi
|
||
No_backupdata=1
|
||
fi
|
||
fi
|
||
Backup_folder="$Backup/$name1"
|
||
app_details="$Backup_folder/app_details.json"
|
||
if [[ -f $app_details ]]; then
|
||
PackageName="$(jq -r '.[] | select(.PackageName != null).PackageName' "$app_details")"
|
||
[[ $PackageName != $name2 ]] && jq --arg name2 "$name2" 'walk(if type == "object" and .PackageName then .PackageName = $name2 else . end)' "$app_details" > "$TMPDIR/temp.json" && mv "$TMPDIR/temp.json" "$app_details"
|
||
echoRgb "上次備份時間$(jq -r --arg entry "Backup time" '.[$entry] | select(.date != null).date' "$app_details" 2>/dev/null)"
|
||
fi
|
||
[[ $hx = USB && $PT = "" ]] && echoRgb "隨身碟意外斷開 請檢查穩定性" "0" && exit 1
|
||
starttime2="$(date -u "+%s")"
|
||
[[ $name2 = com.tencent.mobileqq ]] && echoRgb "QQ可能恢復備份失敗或是丟失聊天記錄,請自行用你信賴的應用備份" "0"
|
||
[[ $name2 = com.tencent.mm ]] && echoRgb "WX可能恢復備份失敗或是丟失聊天記錄,請自行用你信賴的應用備份" "0"
|
||
apk_number="$(echo "$apk_path" | wc -l)"
|
||
if [[ $nobackup != true ]]; then
|
||
if [[ $apk_number = 1 ]]; then
|
||
Backup_apk "非Split Apk" "3"
|
||
else
|
||
Backup_apk "Split Apk支持備份" "3"
|
||
fi
|
||
if [[ $result = 0 && $No_backupdata = "" ]]; then
|
||
if [[ $Backup_Mode = true ]]; then
|
||
if [[ $Backup_obb_data = true ]]; then
|
||
if [[ $name2 != bin.mt.plus ]]; then
|
||
#備份data數據
|
||
[[ $name1 = Nekogram ]] && rm -rf /data/media/0/Android/data/tw.nekomimi.nekogram/files/Telegram/Telegram\ {Video,Stories,Documents,Images}/{*,.*} 2>/dev/null
|
||
Backup_data "data"
|
||
#備份obb數據
|
||
Backup_data "obb"
|
||
else
|
||
echoRgb "$name1無法備份" "0"
|
||
fi
|
||
fi
|
||
#備份user數據
|
||
[[ $name2 != bin.mt.plus ]] && {
|
||
[[ $Backup_user_data = true ]] && {
|
||
Backup_data "user"
|
||
Backup_data "user_de"
|
||
}
|
||
}
|
||
[[ $name2 = github.tornaco.android.thanos ]] && Backup_data "thanox" "$(find "/data/system" -name "thanos"* -maxdepth 1 -type d 2>/dev/null)"
|
||
fi
|
||
fi
|
||
[[ -f $Backup_folder/${name2}.sh ]] && rm -rf "$Backup_folder/${name2}.sh"
|
||
[[ ! -f $Backup_folder/recover.sh ]] && touch_shell "3" "$Backup_folder/recover.sh"
|
||
[[ ! -f $Backup_folder/backup.sh ]] && touch_shell "1" "$Backup_folder/backup.sh"
|
||
fi
|
||
endtime 2 "$name1 備份" "3"
|
||
lxj="$(echo "$Occupation_status" | awk '{print $3}' | sed 's/%//g')"
|
||
echoRgb "完成$((i * 100 / r))% $hx$(echo "$Occupation_status" | awk 'END{print "剩餘:"$1"使用率:"$2}')" "3"
|
||
rgb_d="$rgb_a"
|
||
rgb_a=188 # ANSI 256色: 淺灰色分隔線
|
||
echoRgb "_________________$(endtime 1 "已經")___________________"
|
||
rgb_a="$rgb_d"
|
||
else
|
||
echoRgb "$name1[$name2] 不在安裝列表,備份個寂寞?" "0"
|
||
fi
|
||
if [[ $i = $r ]]; then
|
||
endtime 1 "應用備份" "3"
|
||
#設置無障礙開關
|
||
if [[ $var != "" ]]; then
|
||
if [[ $var != null ]]; then
|
||
settings put secure enabled_accessibility_services "$var" &>/dev/null
|
||
echo_log "設置無障礙"
|
||
settings put secure accessibility_enabled 1 &>/dev/null
|
||
echo_log "打開無障礙開關"
|
||
fi
|
||
fi
|
||
#設置鍵盤
|
||
if [[ $keyboard != "" ]]; then
|
||
ime enable "$keyboard" &>/dev/null
|
||
ime set "$keyboard" &>/dev/null
|
||
settings put secure default_input_method "$keyboard" &>/dev/null
|
||
echo_log "設置鍵盤$(appinfo2 "${keyboard%/*}" 2>/dev/null)"
|
||
fi
|
||
update_apk2="${update_apk2:="暫無更新"}"
|
||
add_app2="${add_app2:="暫無更新"}"
|
||
echoRgb "\n -已更新的apk=\"$osn\"\n -已新增的備份=\"$osk\"\n -apk版本號無變化=\"$osj\"\n -下列為版本號已變更的應用\n$update_apk2\n -新增的備份....\n$add_app2\n -包含SSAID的應用\n$SSAID_apk2" "3"
|
||
notification "101" "app備份完成 $(endtime 1 "應用備份" "3")"
|
||
[[ $txt2 != "" ]] && {
|
||
echo "$txt2" | sort | sed '/^$/d'>"$txt_path2"
|
||
}
|
||
if [[ $backup_media = true && ! -f ${0%/*}/app_details.json ]]; then
|
||
A=1
|
||
B="$(echo "$Custom_path" | egrep -v '#|#' | awk 'NF != 0 { count++ } END { print count }')"
|
||
if [[ $B != "" ]]; then
|
||
echoRgb "備份結束,備份多媒體" "1"
|
||
notification "102" "Media備份開始"
|
||
starttime1="$(date -u "+%s")"
|
||
Backup_folder="$Backup/Media"
|
||
[[ ! -f $Backup/start.sh ]] && touch_shell "2" "$Backup/start.sh"
|
||
[[ ! -d $Backup_folder ]] && mkdir -p "$Backup_folder"
|
||
app_details="$Backup_folder/app_details.json"
|
||
[[ ! -f $app_details ]] && echo "{\n}">"$app_details"
|
||
mediatxt="$Backup/mediaList.txt"
|
||
[[ ! -f $mediatxt ]] && echo "#不需要恢復的資料夾請在開頭使用#注釋 比如:#Download" > "$mediatxt"
|
||
echo "$Custom_path" | sed -e '/^#/d; /^$/d; s/\/$//' > "$TMPDIR/custom_paths"
|
||
while read; do
|
||
echoRgb "備份第$A/$B個資料夾 剩下$((B - A))個" "3"
|
||
notification "102" "備份第$A/$B個資料夾 剩下$((B - A))個"
|
||
starttime2="$(date -u "+%s")"
|
||
if [[ ${REPLY##*/} = adb ]]; then
|
||
if [[ $ksu != ksu ]]; then
|
||
echoRgb "Magisk adb"
|
||
Backup_data "${REPLY##*/}" "$REPLY"
|
||
else
|
||
echoRgb "KernelSU adb不支持備份" "0"
|
||
Set_back_0
|
||
fi
|
||
else
|
||
Backup_data "${REPLY##*/}" "$REPLY"
|
||
fi
|
||
endtime 2 "${REPLY##*/}備份" "1"
|
||
echoRgb "完成$((A * 100 / B))% $hx$(echo "$Occupation_status" | awk 'END{print "剩餘:"$1"使用率:"$2}')" "2"
|
||
rgb_d="$rgb_a"
|
||
rgb_a=188 # ANSI 256色: 淺灰色分隔線
|
||
echoRgb "_________________$(endtime 1 "已經")___________________"
|
||
rgb_a="$rgb_d" && A=$((A + 1))
|
||
done < "$TMPDIR/custom_paths"
|
||
echoRgb "目錄↓↓↓\n -$Backup_folder"
|
||
notification "102" "Media備份完成 $(endtime 1 "自定義備份")"
|
||
endtime 1 "自定義備份"
|
||
else
|
||
echoRgb "自定義路徑為空 無法備份" "0"
|
||
fi
|
||
fi
|
||
fi
|
||
i=$((i + 1)); en=$((en + 1)); nskg=$((nskg + 1))
|
||
done
|
||
}
|
||
|
||
# ===================== 子函數: 清理與統計 =====================
|
||
finalize_backup() {
|
||
backup_wifi "$Backup/wifi"
|
||
Set_screen_pause_seconds off
|
||
[[ $user != 0 ]] && am stop-user "$user"
|
||
Calculate_size "$Backup"
|
||
echoRgb "批量備份完成"
|
||
echoRgb "備份結束時間$(date +"%Y-%m-%d %H:%M:%S")"
|
||
starttime1="$TIME"
|
||
endtime 1 "批量備份開始到結束"
|
||
notification "105" "備份完成 $(endtime 1 "批量備份開始到結束")"
|
||
[[ -f $txt_path ]] && chown "$(stat -c '%u:%g' '/data/media/0/Download')" "$txt_path"
|
||
[[ -f $txt_path2 ]] && chown "$(stat -c '%u:%g' '/data/media/0/Download')" "$txt_path2"
|
||
exit 0
|
||
}
|
||
|
||
# ===================== 重構後的 backup() 入口 =====================
|
||
backup() {
|
||
validate_backup_params
|
||
prepare_app_list
|
||
init_backup_storage
|
||
backup_applications_loop
|
||
finalize_backup
|
||
}
|
||
backup_update_apk() {
|
||
Update_backup='true'
|
||
backup
|
||
}
|
||
backup_media() {
|
||
self_test
|
||
backup_path
|
||
echoRgb "假設反悔了要終止腳本請儘速離開此腳本點擊start.sh選擇終止腳本,否則腳本將繼續執行直到結束" "0"
|
||
A=1
|
||
B="$(echo "$Custom_path" | egrep -v '#|#' | awk 'NF != 0 { count++ } END { print count }')"
|
||
if [[ $B != "" ]]; then
|
||
starttime1="$(date -u "+%s")"
|
||
Backup_folder="$Backup/Media"
|
||
[[ ! -d $Backup_folder ]] && mkdir -p "$Backup_folder"
|
||
[[ ! -f $Backup/start.sh ]] && touch_shell "2" "$Backup/start.sh"
|
||
[[ ! -d $Backup/tools ]] && cp -r "$tools_path" "$Backup"
|
||
[[ ! -f $Backup/restore_settings.conf ]] && update_Restore_settings_conf>"$Backup/restore_settings.conf"
|
||
app_details="$Backup_folder/app_details.json"
|
||
[[ ! -f $app_details ]] && echo "{\n}">"$app_details"
|
||
filesize="$(find "$Backup_folder" -type f -printf "%s\n" 2>/dev/null | awk '{s+=$1} END {print s}')"
|
||
mediatxt="$Backup/mediaList.txt"
|
||
[[ ! -f $mediatxt ]] && echo "#不需要恢復的資料夾請在開頭使用#注釋 比如:#Download" > "$mediatxt"
|
||
Set_screen_pause_seconds on
|
||
notification "109" "Media備份開始"
|
||
echo "$Custom_path" | sed -e '/^#/d; /^$/d; s/\/$//' > "$TMPDIR/custom_paths"
|
||
while read; do
|
||
echoRgb "備份第$A/$B個資料夾 剩下$((B - A))個" "3"
|
||
starttime2="$(date -u "+%s")"
|
||
if [[ ${REPLY##*/} = adb ]]; then
|
||
if [[ $ksu != ksu ]]; then
|
||
echoRgb "Magisk adb"
|
||
Backup_data "${REPLY##*/}" "$REPLY"
|
||
fi
|
||
else
|
||
Backup_data "${REPLY##*/}" "$REPLY"
|
||
fi
|
||
endtime 2 "${REPLY##*/}備份" "1"
|
||
echoRgb "完成$((A * 100 / B))% $hx$(echo "$Occupation_status" | awk 'END{print "剩餘:"$1"使用率:"$2}')" "2" && echoRgb "____________________________________" && A=$((A + 1))
|
||
done < "$TMPDIR/custom_paths"
|
||
Calculate_size "$Backup_folder"
|
||
Set_screen_pause_seconds off
|
||
endtime 1 "自定義備份"
|
||
notification "109" "Media備份完成 $(endtime 1 "自定義備份")"
|
||
else
|
||
echoRgb "自定義路徑為空 無法備份" "0"
|
||
fi
|
||
}
|
||
Set_screen_pause_seconds () {
|
||
if [[ $1 = on ]]; then
|
||
#獲取系統設置的無操作息屏秒數
|
||
if [[ $Get_dark_screen_seconds = "" ]]; then
|
||
Get_dark_screen_seconds="$(settings get system screen_off_timeout)"
|
||
#設置30分鐘後息屏
|
||
settings put system screen_off_timeout 1800000
|
||
echo_log "設置無操作息屏時間30分鐘"
|
||
fi
|
||
[[ $setDisplayPowerMode = true ]] && {
|
||
setDisplay 0
|
||
echo_log "設置螢幕狀態false"
|
||
}
|
||
elif [[ $1 = off ]]; then
|
||
if [[ $Get_dark_screen_seconds != "" ]]; then
|
||
settings put system screen_off_timeout "$Get_dark_screen_seconds"
|
||
echo_log "設置無操作息屏時間為$Get_dark_screen_seconds"
|
||
input keyevent 224
|
||
fi
|
||
[[ $setDisplayPowerMode = true ]] && {
|
||
setDisplay 2
|
||
echo_log "設置螢幕狀態true"
|
||
}
|
||
fi
|
||
}
|