feat: 遠程備份 WebDAV/FTP/SMB/SCP + 內置二進制 + 日誌修復

This commit is contained in:
RainySY
2026-05-12 21:00:10 +08:00
parent 0bc0b95398
commit b2409700c5
6 changed files with 131 additions and 25 deletions

View File

@@ -43,6 +43,7 @@
| ⬛ 黑名單模式 | 黑名單應用可選「完全忽略」或「僅備份安裝包」 |
| ⬜ 白名單支援 | 支援預裝應用白名單與系統應用白名單,可指定備份範圍 |
| 📱 進程偵測 | 可設定忽略正在運行中的應用,避免備份數據不一致 |
| ☁️ 遠程備份 | 支援 WebDAV / FTP / SMB / SCP 四種協議,備份完成後自動上傳到遠端伺服器 |
---
@@ -84,6 +85,8 @@ backup_script.zip
│ ├── busybox # 核心工具集
│ ├── zstd # zstd 壓縮工具
│ ├── tar # tar 打包工具
│ ├── curl # 遠程傳輸工具 (WebDAV/FTP/SMB)
│ ├── scp / ssh # SCP 遠程傳輸
│ ├── jq # JSON 處理
│ ├── bc # 數學計算
│ ├── find # 文件搜索
@@ -128,6 +131,10 @@ backup_script.zip
| `system` | 系統應用白名單包名列表 | Google 系列 |
| `Compression_method` | 壓縮算法:`zstd``tar` | `zstd` |
| `rgb_a` / `rgb_b` / `rgb_c` | 終端輸出主色輔色256 色代碼) | `226` / `123` / `177` |
| `remote_type` | 遠程備份協議:`webdav` / `ftp` / `smb` / `scp`(留空不啟用) | 空 |
| `remote_url` | 遠程伺服器地址(見下方格式說明) | 空 |
| `remote_user` | 遠程認證用戶名 | 空 |
| `remote_pass` | 遠程認證密碼 | 空 |
---
@@ -175,6 +182,31 @@ backup_script.zip
---
### 遠程備份
備份完成後自動將備份檔案上傳到遠端伺服器,支援四種協議:
| 協議 | `remote_url` 格式 |
|------|-------------------|
| WebDAV | `http://192.168.1.100:8080/dav/backup/` |
| FTP | `ftp://192.168.1.100/backup/` |
| SMB | `smb://192.168.1.100/share/backup/` |
| SCP | `192.168.1.100:/home/user/backup/` |
**設定方式:** 編輯 `backup_settings.conf`
```conf
remote_type=webdav
remote_url=http://192.168.1.100:8080/dav/backup/
remote_user=用戶名
remote_pass=密碼
```
**SCP 注意事項:** SCP 優先使用 `sshpass` 進行密碼認證,若不支援則自動嘗試 SSH 密鑰認證。需確保遠端已安裝 SSH 伺服器。
**上傳範圍:** 僅上傳備份數據應用檔案、WiFi、appList.txt排除 `tools/``start.sh``restore_settings.conf` 等腳本文件。
---
## 🔄 腳本更新方式
支援以下四種更新方式:

View File

@@ -123,12 +123,14 @@ rgb_b=123
rgb_c=177
#遠程備份類型 (留空不啟用)
#webdav 或 smb
#webdav 、 ftp 或 smb 或 scp
remote_type=
#遠程地址
#WebDAV例: http://192.168.1.100:8080/dav/
#SMB例: //192.168.1.100/backup
#FTP例: ftp://192.168.1.100/backup/
#SMB例: smb://192.168.1.100/backup/
#SCP例: 192.168.1.100:/home/user/backup/
remote_url=
#遠程認證用戶名

BIN
tools/curl Normal file

Binary file not shown.

BIN
tools/scp Normal file

Binary file not shown.

BIN
tools/ssh Normal file

Binary file not shown.

View File

@@ -133,12 +133,14 @@ rgb_b="${rgb_b:-123}"
rgb_c="${rgb_c:-177}"
#遠程備份類型 (留空不啟用)
#webdav 或 smb
#webdav 、 ftp 或 smb 或 scp
remote_type="${remote_type:-}"
#遠程地址
#WebDAV例: http://192.168.1.100:8080/dav/
#SMB例: //192.168.1.100/backup
#FTP例: ftp://192.168.1.100/backup/
#SMB例: smb://192.168.1.100/backup/
#SCP例: 192.168.1.100:/home/user/backup/
remote_url="${remote_url:-}"
#遠程認證用戶名
@@ -468,7 +470,8 @@ kill_Serve() {
kill_Serve
# -------- 遠程備份功能 --------
_find_curl() {
for p in /data/user/0/bin.mt.plus/files/term/bin/curl /system/bin/curl curl; do
for p in "$tools_path/curl" curl /data/user/0/bin.mt.plus/files/term/bin/curl /system/bin/curl; do
[[ -f $p ]] && chmod +x "$p" 2>/dev/null
[[ -x $p ]] && { CURL="$p"; return 0; }
done
return 1
@@ -476,27 +479,27 @@ _find_curl() {
upload_remote() {
local proto="$1"
[[ $proto = scp ]] && { upload_scp; return $?; }
[[ -z $remote_url ]] && { echoRgb "remote_url未設置" "0"; return 1; }
local base_url
case $proto in
smb)
base_url="${remote_url#//}"
base_url="smb://${base_url#smb://}"
;;
webdav)
base_url="${remote_url%/}"
[[ $base_url != http://* && $base_url != https://* ]] && { echoRgb "WebDAV地址格式錯誤: $remote_url" "0"; return 1; }
;;
ftp|smb)
base_url="$remote_url"
[[ $proto = ftp && $base_url != ftp://* ]] && { echoRgb "FTP地址格式錯誤需 ftp:// 開頭" "0"; return 1; }
;;
esac
CURL=""
_find_curl || { echoRgb "未找到curl無法上傳" "0"; return 1; }
echoRgb "使用: $CURL" "2"
local failed=0
local list_file="$TMPDIR/.rlist"
local dirs_file="$TMPDIR/.rdirs"
[[ -z $Backup ]] && { echoRgb "Backup路徑為空" "0"; return 1; }
find "$Backup" -type f ! -path "*/tools/*" ! -name 'start.sh' ! -name 'restore_settings.conf' > "$list_file"
# 提取所有目錄並在遠程創建 (WebDAV MKCOL, SMB 跳過)
# WebDAV: 創建遠程目錄 (MKCOL), FTP: curl --ftp-create-dirs 自動處理
if [[ $proto = webdav ]]; then
while read -r f; do
local d="${f#$Backup/}"
@@ -517,20 +520,86 @@ upload_remote() {
while read -r f; do
[[ -z $f ]] && continue
local rel="${f#$Backup/}"
local enc_rel
[[ $proto = webdav ]] && enc_rel=$(echo -n "$rel" | busybox sed 's/%/%25/g; s/ /%20/g; s/+/%2B/g; s/#/%23/g')
[[ $proto = smb ]] && enc_rel="$rel"
local target_url="$base_url/$enc_rel"
[[ $proto = smb ]] && target_url="$base_url/$rel"
echoRgb "上傳: $target_url" "2"
if "$CURL" -sSf -T "$f" -u "$remote_user:$remote_pass" "$target_url"; then
rm -f "$f"
local target_url
if [[ $proto = webdav ]]; then
local enc_rel=$(echo -n "$rel" | busybox sed 's/%/%25/g; s/ /%20/g; s/+/%2B/g; s/#/%23/g')
target_url="$base_url/$enc_rel"
else
failed=1
break
target_url="$base_url/$rel"
fi
echoRgb "上傳($proto): $rel" "2"
if [[ $proto = ftp ]]; then
"$CURL" -sSf --ftp-create-dirs -T "$f" -u "$remote_user:$remote_pass" "$target_url"
else
"$CURL" -sSf -T "$f" -u "$remote_user:$remote_pass" "$target_url"
fi || { failed=1; break; }
rm -f "$f"
done < "$list_file"
rm -f "$list_file" "$dirs_file" 2>/dev/null
rm -f "$list_file" 2>/dev/null
if [[ $failed -eq 0 ]]; then
echoRgb "遠程上傳完成" "1"
else
echoRgb "遠程上傳失敗,本地檔案已保留" "0"
return 1
fi
}
upload_scp() {
[[ -z $remote_url ]] && { echoRgb "remote_url未設置" "0"; return 1; }
local SCP SSH
local use_sshpass
command -v sshpass >/dev/null 2>&1 && use_sshpass=1
for p in "$tools_path/scp" scp /data/user/0/bin.mt.plus/files/term/bin/scp; do
[[ -f $p ]] && chmod +x "$p" 2>/dev/null
[[ -x $p ]] && { SCP="$p"; break; }
done
for p in "$tools_path/ssh" ssh /data/user/0/bin.mt.plus/files/term/bin/ssh; do
[[ -f $p ]] && chmod +x "$p" 2>/dev/null
[[ -x $p ]] && { SSH="$p"; break; }
done
[[ -z $SCP || -z $SSH ]] && { echoRgb "未找到scp/ssh無法上傳" "0"; return 1; }
local host="${remote_url#//}"
local rpath
if [[ $host = *:* ]]; then
rpath="${host#*:}"
host="${host%%:*}"
elif [[ $host = */* ]]; then
rpath="/${host#*/}"
host="${host%%/*}"
else
rpath="/"
fi
[[ -z $host ]] && { echoRgb "SCP地址格式錯誤例: 192.168.1.100:/path" "0"; return 1; }
local opts="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ConnectTimeout=10"
# 檢查連接
if [[ -n $use_sshpass ]]; then
sshpass -p "$remote_pass" "$SSH" $opts "$remote_user@$host" "echo ok" >/dev/null 2>&1 \
|| { echoRgb "SCP密碼或主機錯誤" "0"; return 1; }
elif [[ $remote_user != "" ]]; then
"$SSH" -o BatchMode=yes -o ConnectTimeout=5 $opts "$remote_user@$host" "echo ok" >/dev/null 2>&1 \
|| { echoRgb "SCP需密鑰認證或sshpass (未安裝)" "0"; return 1; }
else
echoRgb "remote_user未設置" "0"; return 1
fi
local failed=0
local list_file="$TMPDIR/.slist"
find "$Backup" -type f ! -path "*/tools/*" ! -name 'start.sh' ! -name 'restore_settings.conf' > "$list_file"
while read -r f; do
[[ -z $f ]] && continue
local rel="${f#$Backup/}"
local target="$remote_user@$host:$rpath/$rel"
echoRgb "上傳(SCP): $rel" "2"
# 創建遠程目錄
if [[ -n $use_sshpass ]]; then
sshpass -p "$remote_pass" "$SSH" $opts "$remote_user@$host" "mkdir -p '$rpath/${rel%\/*}'" 2>/dev/null
sshpass -p "$remote_pass" "$SCP" $opts "$f" "$target" || { failed=1; break; }
else
"$SSH" $opts "$remote_user@$host" "mkdir -p '$rpath/${rel%\/*}'" 2>/dev/null
"$SCP" $opts "$f" "$target" || { failed=1; break; }
fi
rm -f "$f"
done < "$list_file"
rm -f "$list_file" 2>/dev/null
if [[ $failed -eq 0 ]]; then
echoRgb "遠程上傳完成" "1"
else
@@ -544,7 +613,7 @@ remote_setup() {
echoRgb "遠程備份: $remote_type -> $remote_url" "3"
case $remote_type in
smb|webdav)
webdav|ftp|smb|scp)
echoRgb "備份完成後將自動上傳到遠端" "3"
;;
*) echoRgb "未知遠程類型: $remote_type" "0"; return 1 ;;
@@ -553,8 +622,10 @@ remote_setup() {
remote_cleanup() {
case $remote_type in
smb) upload_remote "smb" ;;
webdav) upload_remote "webdav" ;;
ftp) upload_remote "ftp" ;;
smb) upload_remote "smb" ;;
scp) upload_remote "scp" ;;
*) return 0 ;;
esac
}
@@ -810,7 +881,8 @@ if [ -f \"$MODDIR_Path/tools/tools.sh\" ]; then
else
echo \"$MODDIR_Path/tools/tools.sh遺失\"
fi
logfile=\"\${0%/*}/log_\$(date +%Y-%m-%d_%H-%M).txt\"
mkdir -p \"\${0%/*}/log\" 2>/dev/null
logfile=\"\${0%/*}/log/log_\$(date +%Y-%m-%d_%H-%M).txt\"
. \"$MODDIR_Path/tools/tools.sh\" | tee \"\$logfile\"
sed -i \"\$(printf 's/\033\[[0-9;]*m//g')\" \"\$logfile\"" > "$2"
}