一对"账房先生"
如果说 disable.sh 与 restore.sh 是动手的左右手,那 recovery.py 与 check.py 就是工具链里的账房先生——一个管"事前记账",一个管"事后对账"。
| 脚本 | 出场时机 | 核心职责 |
|---|---|---|
| recovery.py | 任何修改之前 | 写下 disable.sh 需要的恢复记录,并打印恢复批处理 |
| check.py | 固件升级之后(或任何时候) | 比对电视与应用清单,查固件升级撤掉了什么;--fix 恢复 |
一个守住起点,一个看住过程。两者合力,"可恢复"才不只是一句口号。
recovery.py:把案发现场拍下来
为什么先记账
恢复的依据是"改之前什么样"。这个"之前"不会自动留在世上——电视不会给你拍快照,你的记忆更不可靠(三个月后你绝对想不起禁过哪个应用)。recovery.py 的工作,就是在动手之前把电视当前的应用包状态完整记录下来,写成 disable.sh 需要的恢复记录。
这份记录就是 ct-0402 里反复强调的"案卷":restore.sh 撤销时读它,日后固件升级后核对时也读它。
何时运行
一个黄金法则:只要准备对电视做任何应用层面的修改,先跑 recovery.py。 只跑一次就能覆盖后续多次修改——除非中间电视固件升级过,那时建议重新记一次账(见下文 check.py 部分)。
执行与预期输出
连接就绪后,在项目根目录运行:
python3 tools/recovery.py
(连接参数如 --ip 的传入方式、记录文件的命名规则,以工具内 --help 和仓库 README 为准。)
预期看到两样产出:
- 一份恢复记录文件落在项目目录里,文件名通常带有电视标识或时间信息(以实际输出为准)。记下它的名字,这是你的后悔药。
- 一段恢复批处理打印在屏幕上——按记录逐条恢复启用应用的命令序列。它是记录文件的"人类可读版",关键时刻可以直接照着敲。
确认点
| 检查项 | 预期 |
|---|---|
| 脚本无报错跑完 | 无异常堆栈,正常退出 |
| 记录文件生成 | 项目目录里出现新文件,你知道它的位置 |
| 批处理有内容 | 屏幕上打印出成规模的命令序列,不是空跑 |
三项都满足,才算记账完成,才配谈"动手"。
记录文件里有什么
第一次跑完 recovery.py,很多人会盯着生成的文件犯嘀咕:这里面到底存了什么?简单说,它是一份"改前快照":电视上现存的应用名单,连同它们当时的状态(启用还是已停用、是否随系统预装等,具体字段以脚本输出为准)。disable.sh 需要的恢复记录正是从这份快照里提取的——哪些应用在修改前是启用的,撤销时就该回到启用。
理解这一点,你就明白了两件事。其一,恢复不是"凭记忆恢复",而是"凭快照恢复",所以快照的准确性就是撤销的准确性。其二,快照有时效性:电视固件升级、应用更新、系统重置之后,旧快照描述的可能不再是现实。因此本书的建议是:每次动手修改之前,都重新跑一次 recovery.py,让案卷永远比现实只旧不新。
check.py:固件升级后的核对
一个常见场景
电视系统隔三差五升级固件。升级之后,不少用户发现:咦,之前禁掉的某个预装应用又回来了;某个设置也复位了。这不是你的操作失误,而是固件升级把部分系统状态"洗"回了出厂配置——被停用的应用、被改过的默认项,都可能被还原。
问题在于:你不知道它撤了什么。凭记忆逐个查?不现实。check.py 就是为这个场景而生的。
它做什么
check.py 做一次三方比对:电视当前的实际状态、工具链里的应用清单、以及你的恢复记录。比对结果会明确指出:哪些禁用被固件升级撤掉了、哪些设置被复位了。一句话——它把"电视背着你干了什么"列成一张清单。
执行与预期输出
连接就绪后运行:
python3 tools/check.py
预期看到:一份比对报告,列出"被还原的禁用项"(具体格式以实际输出为准)。报告为空,说明状态完好,虚惊一场;报告有内容,就进入下一步——恢复。
python3 tools/check.py --fix
预期看到:脚本按比对结果逐项恢复,输出处理明细,最后汇总"恢复 X 项"。跑完再运行一次不带 --fix 的 check.py 复查,报告应为空,即闭环。
一个典型时间线
flowchart TD
A[recovery.py 记录改前状态] --> B[disable.sh 执行禁用]
B --> C[日常使用]
C --> D[电视固件升级]
D --> E[check.py 比对]
E --> F{有被还原的项?}
F -->|是| G[check.py --fix 恢复]
G --> H[复查 check.py 为空]
F -->|否| H
注意图中"固件升级后重新记账"的隐含建议:升级会改变系统状态,若你打算在升级后继续调整应用,先跑一次 recovery.py 更新案卷,再动手。
三方对账的逻辑
check.py 的报告为什么可信?因为它不是拿单一来源下结论,而是做三方比对:电视当前的实际状态是一方,工具链内置的应用清单是一方,你的恢复记录是一方。三方摆在一起,差异项自然浮出水面——电视现在是启用、而你的记录里是停用的应用,就是被固件升级还原的对象;记录里没有、电视上却出现了的,是升级带来的新预装。
这种"对账"思路的好处是抗误判:只拿电视和记录两方比,分不清"被还原"和"你手动恢复过";只拿电视和内置清单比,又认不出你的个性化调整。三方齐备,报告才既全面又指得准。理解了这套逻辑,报告里每一行的来路你就都看得懂了。
输出怎么读
check.py 与 recovery.py 的输出多为列表形式,阅读时抓住三列信息就够:
| 信息 | 含义 | 你的动作 |
|---|---|---|
| 应用包名 | 出问题的应用是谁 | 对照清单回忆它是什么 |
| 当前状态 | 现在是被禁、启用还是未安装 | 判断与预期的差距 |
| 建议动作 | 脚本给出的处理建议 | --fix 即按建议批量恢复 |
如果报告里出现你没见过的应用,别慌——那是固件升级带来的新预装,Check 只是如实上报。要不要处理,参照 ct-0304 的三类别四问,照你的习惯来。
日常维护的三个时机
这对账房先生不需要天天打扰,但在三个时机出场,价值最大。第一,任何修改之前:recovery.py 先跑,案卷先行,这是老规矩。第二,电视固件升级之后:check.py 立刻核对,被还原的禁用项用 --fix 修回,几分钟的事,别攒着。第三,你产生怀疑的时候——"那个预装是不是又回来了""设置好像复位了"——与其猜,不如跑一次 check.py,让数据说话。
把这三个时机变成条件反射,你的电视就能长期待在"你满意的状态"附近,而不是每升一次级就向出厂状态滑坡一截。
常见问题
问:check.py 能查出"我误禁了但还没发现"的应用吗?
答:不完全能。它的比对基准是清单与记录,不是你的使用习惯。误禁的发现仍要靠使用中的观察和 ct-0305 的测试;一旦确认误禁,用 restore.sh 或记录里的批处理恢复。
问:多久跑一次 check.py 合适?
答:两个时机雷打不动:电视固件升级之后,以及你感觉"某个预装好像又回来了"的时候。平时不必定期跑。
问:--fix 会不会误伤?
答:--fix 只动比对报告里列出的项,不碰报告之外的应用。稳妥起见,--fix 之前先跑一次 recovery.py 更新记录,给自己留好这轮的退路。
问:recovery.py 和 check.py 都要在电脑上跑吗?
答:是。它们与 disable.sh 一样,在电脑侧通过 ADB 通道工作,电视端无需安装任何东西。
问:recovery.py 会改动电视上的任何东西吗?
答:不会。它只读取电视当前的应用状态并生成本地记录,是只读操作,跑它对电视零影响。真正动手的是后续的 disable.sh,这也是"先记账后动手"顺序的由来。
问:recovery.py 和 check.py 的输出可以存档当文档吗?
答:可以,而且推荐。把每次的记录文件和核对报告按日期归置在项目目录里,日后再遇到问题,这就是电视的"体检档案",比任何回忆都可靠。
小结
recovery.py 负责"事前留底",check.py 负责"事后对账";一个让修改可逆,一个让时间(固件升级)可查。用好这对账房先生的要领只有一句:修改前先 recovery,升级后跑 check,恢复之前再备份。 下一篇 ct-0404,我们转向两个更"工程"的工具:b64push.py 与 relay.py。
