Hello!这里是 Thousandbundles 的ADB 控制与云端迁移实践。
在正篇里,咱们已经把 2 核 2G 学生机收拾干净、用 EasyTier 搭好了专属虚拟内网,并把大肥鱼(DSH)、百炼免费 API 和 NapCat QQ 机器人跑通了。因为正篇字数直接塞满了平台上限,这里把大家问得最多的两个进阶番外单独拎出来做成一篇:
- 番外一:怎么让云端的大肥鱼通过 EasyTier 虚拟内网 + ADB 直接接管你的备用手机(远程亮屏、截图发回 QQ、自动点击做定时签到)
- 番外二:怎么把自己在 Windows 电脑上已经养熟的大肥鱼(插件、配置、历史对话、密钥)挑拣打包,无损搬到 Linux 云服务器上
番外一|让云端的大肥鱼 adb 接管你的手机
正篇第五步把手机通过 EasyTier 接入虚拟内网之后,其实有一个特别好玩的隐藏能力:云端的服务器可以直接连到你手机上。只要手机把 adb 的网络端口开出来,大肥鱼就能截图、点击、装应用,等于把备用手机交给它使唤。
链路很短:服务器 → EasyTier 虚拟内网 → 手机的 adb 端口。全程分五步,手机那边只折腾一次。
第一步:手机上开好调试权限,把 adb 网络端口开出来
- 先在手机「开发者选项」里把开关开齐: 除了打开 「USB 调试」 之外,还要注意国产系统的必开项—— 小米 / Redmi(MIUI / 澎湃 OS):必须同时打开底下的 「USB 调试(安全设置)」(要插 SIM 卡并登录小米账号才能开),否则后面只允许截图、不允许模拟点击和滑动 OPPO / 一加 / realme / vivo:记得滑到底部打开 「禁止权限监控」(或「模拟点击」开关),并关掉“连接超时自动关闭 USB 调试” 华为 / 荣耀(HarmonyOS / MagicOS):同时打开 「“仅充电”模式下允许 ADB 调试」。
- 插上数据线连到电脑(电脑要先装好
platform-tools,如果不想装也可以直接打开网页版 WebADBhttps://app.webadb.com在浏览器里连手机点一下ADB over WiFi激活 5555 端口),然后在电脑终端跑:
adb devices # 确认电脑能看到手机(手机弹窗勾选“始终允许”并点确定)
adb tcpip 5555 # 把 adb 切成网络模式,端口固定为 5555
拔掉数据线,端口就保持住了。注意:部分华为 / 荣耀 / OPPO 机型默认会在拔掉数据线的一瞬间自动关闭 USB 调试,如果发现一拔线就连不上,先在手机通知栏把 USB 用途从“仅充电”改成 “传输文件(MTP)”,再执行 adb tcpip 5555 后拔线。另外手机重启后 5555 端口会失效,重启后需要重新插一次线激活。
(补充:Android 11 及以上其实可以完全不用电脑和数据线,直接在手机「开发者选项 → 无线调试」里开:先把手机连上 EasyTier 固定为 10.144.144.3,点进手机无线调试的「使用配对码配对设备」,直接在云服务器终端跑 adb pair 10.144.144.3:配对端口 输一次 6 位配对码,再跑 adb connect 10.144.144.3:无线调试主页面显示的端口 就能连上;或者在手机无线调试开启的状态下,在云服务器跑 adb connect 10.144.144.3:无线端口 && adb -s 10.144.144.3:无线端口 tcpip 5555,也能直接在云端把手机切到固定的 5555 端口。)
第二步:给手机固定一个内网 IP 并锁定后台
打开手机上的 EasyTier 客户端,不要勾 DHCP,手动把虚拟 IPv4 填成 10.144.144.3(别和服务器 .1、电脑 .2 撞)。用 DHCP 的话哪天分配变了,adb 就连不上了。
同时,在手机的多任务界面把 EasyTier 卡片下拉加锁,并在手机电池设置里把 EasyTier 设为 “无限制 / 允许后台高耗电”,避免手机息屏几分钟后把 EasyTier 后台进程关掉导致断联。
回到服务器确认能通:
ping 10.144.144.3
第三步:服务器装 adb 并连上手机
apt install -y android-tools-adb
adb connect 10.144.144.3:5555
adb devices
adb devices 里出现 10.144.144.3:5555 device 就成了。
注意第一次从云服务器连接时,手机屏幕会弹「是否允许 USB 调试」(因为云服务器生成了一对新的 RSA 密钥),一定要亮屏勾上 “始终允许使用这台计算机进行调试” 再点确定,否则会一直显示 unauthorized。
第四步:验证一下是不是真的能看图、能点屏幕
(注:如果你在正篇第七步选的是纯文本模型 deepseek-v4.1-flash-1017,它本身是不支持直接看图片附件的。想让大肥鱼既能截屏发到 QQ 给你看、又能自己看懂手机屏幕上的按钮位置,有两种办法:一是在百炼后台再勾选一个千问视觉模型比如 qwen-vl-max 或支持视觉的多模态模型;二是顺手装一个 apt install -y python3-uiautomator2 或 tesseract-ocr,让大肥鱼直接读取 Android 界面的 XML 控件树坐标,不仅不用消耗视觉图片 Token,点按钮还比看图估算坐标准得多!)
在服务器终端跑下面几行命令验证:
adb -s 10.144.144.3:5555 shell input keyevent 224 # 先唤醒点亮手机屏幕(防止黑屏截出全黑图)
adb -s 10.144.144.3:5555 exec-out screencap -p > /root/qq-workspace/shot.png # 截一张当前屏幕存进工作区
adb -s 10.144.144.3:5555 shell input tap 540 1200 # 点一下坐标 (540, 1200)
截图能正常拉下来(不是 0 字节也不是全黑)、手机屏幕上真点得动,链路就通了。
第五步:交给大肥鱼(还能把手机截图直接发回你 QQ)
因为咱们正篇第八步装的 dsh-onebot-qq 插件自带了 qq_send_image 发图工具,现在你直接在 QQ 私聊里跟大肥鱼说:
“用
adb connect 10.144.144.3:5555连我手机,先用input keyevent 224亮屏,截张图存到/root/qq-workspace/shot.png并用qq_send_image发给我看看现在是什么界面;如果要点击按钮,优先用uiautomator dump读取界面 XML 控件坐标再点。”
它就会自己敲命令亮屏、截图发到你 QQ 上、解析界面控件坐标再决定下一步点哪里。要让它每天定时干活,还可以让它把流程写成脚本配上 schedule 定时任务,比如每天早上自动唤醒备用机帮你在某几个 App 里把签到点了,点完再截张图发 QQ 向你汇报。
四个容易卡住的地方:
adb devices 显示 unauthorized:手机上没点“允许调试”弹窗。先让手机亮屏停在桌面,再回服务器跑 adb disconnect && adb kill-server && adb connect 10.144.144.3:5555,手机上就会重新弹出授权框
显示 offline 或一拔掉数据线就连不上:手机把 USB 模式设成了“仅充电”导致拔线自动关调试。重插数据线,下拉通知栏把 USB 用途改成“传输文件(MTP)”,再跑一次 adb tcpip 5555
能截图,但 input tap 点了屏幕没反应:小米 / Redmi 忘了开开发者选项里的「USB 调试(安全设置)」,或者 OPPO / vivo 没开「禁止权限监控」,补开之后立即生效
截出来的图是全黑的:手机正处于息屏状态,或者当前界面是银行 / 支付密码页(系统启用了 FLAG_SECURE 防截屏保护)。跑操作前先加一句 adb shell input keyevent 224 亮屏,并给备用机取消锁屏密码(设为“滑动解锁”或“无锁屏”)
⚠️ 安全提醒:这一步等于把手机的控制权交出去了
5555 端口一旦开在网络上,任何能连上你手机 IP 的人,都能完整控制这台手机。这里有两个必须注意的安全细节:
千万别在连着校园网公共 Wi-Fi 时裸开 5555 端口:因为 adb tcpip 5555 监听的是手机的所有网卡(0.0.0.0:5555),不光虚拟内网能连,和你在同一个校园网 Wi-Fi 下的其他人如果扫到你手机的局域网 IP 也能弹调试请求。所以备用机平时建议只开自己的热点或可信 Wi-Fi,组网密码千万别外泄
用完随手断开,且绝对别拿主力机试:平时不用的时候,在服务器上跑一句 adb disconnect 10.144.144.3:5555(或者在手机通知栏点“关闭 USB 调试”),找一台退下来的吃灰备用机专门放宿舍插电挂着最稳。
adb 的能力的权限大小: adb 给你的是
shell权限(比普通 App 权限高,但不是 root)。能做的有:截图录屏、点击滑动输入、读取界面控件树(uiautomator dump)、开关应用、装卸载应用、读写/sdcard共享目录里的照片文件、模拟电源键/返回键/音量键。 做不到的有:修改系统分区文件、直接读取别的 App 的私有沙盒目录(/data/data下面那堆)、绕过指纹或数字锁屏密码、在带有防截屏保护的支付页面截图。 而且如果纯靠“截图 → 调视觉模型看图 → 估坐标点击”,一次循环要两三秒,还要消耗图片 Token;所以实战里让大肥鱼用uiautomator dump读控件坐标 + 关键步骤再截图发 QQ 确认,才是最省钱也最稳的玩法。
番外二|把本地已经养好的肥鱼搬到服务器
不少友友在电脑上早养了一只肥鱼,插件装了一堆、会话攒了几百条,换到服务器上不想从零再配一遍。
但如果你打开 C:\Users\你的用户名\.dsh 看一眼,会发现这文件夹动辄好几个 G,千万别直接整个打包往服务器上拖。里面九成以上都是 Windows 专用的运行环境和编译产物,硬拷过去不仅慢,还会把服务器上的肥鱼直接搞崩。
咱们真正要从 .dsh 里挑出来带走的其实就几样(对照下面实拍图里的绿框):
首先是 profiles\web 底下的 5 个配置文件(package.json、cordis.patch.yml、cordis.yml、pnpm-workspace.yaml、pnpm-lock.yaml),你装了哪些插件、改过什么设置全记在这儿;然后再把根目录下的 sessions(以前聊过的历史记录)、storages(平时的记忆和状态)、.credentials.yaml(填好的 API 密钥)以及 plugins(自己装的插件源码)顺手带上就齐了。至于 attachments 里存的是以前聊天发过的图片,想要留着就一起拷,不拷也不影响正常用。
而占了大头的 profiles\web\node_modules、dsh-runtimes 和 cache(图里标红框的几个)全都不用管。因为 dsh-runtimes 装的是 Windows 版的 Node 和 Python,node_modules 里像 node-pty、ssh2、koffi、cloudflared 这些底层模块也全是在 Windows 下编译出来的 .node 文件,挪到 Linux 上一个都跑不起来,到了服务器让 pnpm install 重新拉一遍 Linux 版就行。另外像 plugins/dsh-infinite-gen-5 这种带二进制分析插件的插件,里面的 runtimes/ 和 third_party/ 占了 2 个 G 全是 Windows 程序,打包时顺手跳过,筛完之后整个压缩包也就二十来兆。
第一步:本地打包(Windows PowerShell)
在你自己的 Windows 电脑上按 Win + R 输入 powershell 回车,把下面整段复制进去运行(脚本会自动定位你的 .dsh 目录,挑出上面那几样打包到电脑桌面,并在跑完后自动弹出资源管理器选中生成的压缩包):
$h = "$HOME\.dsh"
$desk = [Environment]::GetFolderPath("Desktop")
$s = "$desk\dsh-migrate"
Remove-Item $s, "$desk\dsh-migrate.zip" -Recurse -Force -ErrorAction SilentlyContinue
New-Item -ItemType Directory -Force "$s\profiles\web", "$s\plugins" | Out-Null
# 1. 拷走 profiles\web 下的所有配置文件(自动跳过 node_modules 等子文件夹)
Get-ChildItem "$h\profiles\web" -File -ErrorAction SilentlyContinue | Copy-Item -Destination "$s\profiles\web"
# 2. 拷走历史会话、状态与密钥(顺带把 .env 也捎上;想要历史图片就在数组里加个 "attachments")
foreach ($item in @("sessions", "storages", ".credentials.yaml", ".env")) {
if (Test-Path "$h\$item") { Copy-Item "$h\$item" "$s\$item" -Recurse -Force }
}
# 3. 拷走本地插件源码,自动剔除体积巨大的二进制与依赖目录
if (Test-Path "$h\plugins") {
robocopy "$h\plugins" "$s\plugins" /E /XD node_modules .git runtimes third_party | Out-Null
}
Compress-Archive "$s\*" "$desk\dsh-migrate.zip" -Force
Remove-Item $s -Recurse -Force
Write-Host "`n打包完成!压缩包已输出到:$desk\dsh-migrate.zip" -ForegroundColor Green
explorer.exe "/select,$desk\dsh-migrate.zip"
- 本地输出位置:直接生成在你电脑桌面上的
dsh-migrate.zip(比如C:\Users\你的用户名\Desktop\dsh-migrate.zip,开了 OneDrive 的话也会自动存到你的 OneDrive 桌面上,脚本跑完还会自动弹窗帮你选中它,大小一般就 20~25 MB)。 - 上传到服务器哪个位置:打开 FinalShell,看底下【文件】窗口,确认当前路径在
/root(也就是~主目录),把桌面上的dsh-migrate.zip直接拖进去上传成/root/dsh-migrate.zip,这样才跟下面第二步里的unzip -o ~/dsh-migrate.zip对得上。
第二步:服务器上解压并重装 Linux 依赖
# ① 版本尽量和本地对齐(先在本地跑 dsh --version 看一眼版本号,比如 0.1.5-rc.3)
npm i -g @deepseek-ai/dsh@0.1.5-rc.3
# ② 先把服务器上现有的 ~/.dsh 备份起来,防翻车
pm2 stop dsh
mv ~/.dsh ~/.dsh.bak
# ③ 直接按原目录结构解压归位
mkdir -p ~/.dsh
unzip -o ~/dsh-migrate.zip -d ~/.dsh
# ④ 把 package.json 里的 Windows 绝对路径(C:/Users/...)通配替换成 Linux 相对路径
sed -i -E 's#(link|file):[A-Za-z]:/Users/[^"]*/\.dsh/plugins/([^"]*)#file:../../plugins/\2#g' ~/.dsh/profiles/web/package.json
# ⑤ 重装依赖,让原生模块在 Linux 上重新编译
cd ~/.dsh/profiles/web && pnpm install
④ 这一步别跳过。 本地 Windows 装过的插件在 package.json 里常会被记成 "link:C:/Users/你的用户名/.dsh/plugins/插件名" 这种 Windows 盘符绝对路径,不改的话到了 Linux 跑 pnpm install 会直接报错。上面第 ④ 行的正则会自动把所有 C:/Users/.../.dsh/plugins/xxx 替换成跨平台的相对路径 file:../../plugins/xxx。
还有个容易漏的:pnpm-workspace.yaml 一定要跟着搬。里面那段 allowBuilds 白名单是 node-pty、ssh2、koffi 这些原生模块的编译许可,缺了它 pnpm 会拒绝执行构建脚本,插件表面上装好了,一启动就报错。
第三步:启动并验证
NODE_OPTIONS="--max-old-space-size=768" pm2 start "dsh web --host 10.144.144.1 --port 3080 --no-open" --name dsh
pm2 save
sleep 3 && grep -o "http://.*token=[^ ]*" ~/.pm2/logs/dsh-out.log | tail -n 1
拿新打印的 token 链接打开工作台,重点看三样:左侧的工作区列表还在不在、侧边栏的插件是不是都齐、随便点开一个旧会话能不能读。
搞砸了怎么回滚
pm2 stop dsh
rm -rf ~/.dsh
mv ~/.dsh.bak ~/.dsh
pm2 restart dsh
两个提醒
一是 pnpm install 装这套依赖挺吃内存,2 核 2G 务必先确认正篇第三步的 2G Swap 是好的,装的时候瞄一眼 free -h,被 OOM 打断的话重跑一次就行。
二是 .credentials.yaml 里是明文 API Key,sessions 里是完整的聊天记录,这个 zip 传完就删,别留在桌面或者网盘里。
不想保留历史会话的话更省事:跳过 sessions 和 storages 两步,其余照做,服务器上就是个干净的新实例带全套插件。
如果友友们在用 ADB 连备用机或者迁移本地肥鱼时遇到问题,欢迎在评论区留言(截图提问记得把公网 IP 和 Token 打码),觉得有帮助的友友别忘了点个赞、收个藏,我们下期见!