三库 YAML 转义修复(fix-lib-yaml.py)¶
位置:
deploy/nfos/tools/fix-lib-yaml.py| 语言:python3 | 是否需要 root:否
工具性质:会原地改写传入文件的修复器(不是只读工具)
运行前提:需要 PyYAML(唯一带非标准库依赖的工具);目标文件路径由命令行给出
部署状态:随仓库检出运行,不部署到 /opt/Cy/services/system.d/nfos/
用途¶
修复三库 YAML(deploy/nfos/signature-library.yml、rule-library.yml、template-library.yml)里“双引号标量非法转义”的写法。
源码 docstring 记录的病根(逐字引用):
背景:正则模式在 YAML 双引号里必须写成 `\\s`(双反斜杠),
但新增条目写成了 `"\[notice\]"` —— YAML 双引号只认 \\ \" \n \t 等,
`\[` 是非法转义 → yaml.safe_load 整库解析失败 → 平台 signatures=0、apply 报 invalid。
修法(源码 docstring 逐字):
修法:逐行取 `- "..."` 形式的标量,单独试解析;失败则按“反斜杠是字面量”的原意重建:
· 内容不含单引号 → 改成 YAML 单引号(单引号里反斜杠是字面量,最省事)
· 内容含单引号 → 保留双引号,把反斜杠与双引号正确转义
幂等:已正确的行不动。
关键实现边界:
| 环节 | 源码行为 |
|---|---|
| 命中行 | 仅匹配 ^(\s*- )"(.*)"(\s*(?:#.*)?)$,即列表项形式的双引号标量(含行尾注释) |
| 跳过条件 | yaml.safe_load('"..."') 能解析成功 → 该行不动(幂等来源) |
| 兜底 | 单引号版仍不合法(极罕见)→ 退回双引号全转义 |
| 写回 | io.open(path, "w", encoding="utf-8", newline="\n") —— 统一 LF 换行 |
| 打印上限 | 每个文件最多打印前 12 条改动(ch[:12]) |
典型场景¶
- 新增特征条目后平台
signatures=0或/libs/apply报 invalid / 整库解析失败时,先跑一次修转义; - 合并别人提交的三库 YAML(手工编辑容易写出
"\[...\]"这类非法转义)后做一次归一化; - 作为“YAML 双引号里塞正则”的机械修复步骤,配合
yaml.safe_load复验。
用法与参数¶
源码 docstring 给出的用法(逐字引用):
参数只有位置参数,不经过 argparse,直接取 sys.argv[1:]:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
sys.argv[1:] |
一个或多个文件路径 | 空(不修复任何文件) | 逐个文件原地修复;相对路径按当前工作目录解析 |
无参数时的默认行为:不处理任何文件,直接打印 合计修复 0 行 并以 0 退出(不会去猜三库路径)。
示例¶
先备份、再修复、再复验(推荐顺序:本工具没有 --dry-run,也不自己备份):
Copy-Item deploy/nfos/signature-library.yml deploy/nfos/signature-library.yml.bak
python deploy/nfos/tools/fix-lib-yaml.py deploy/nfos/signature-library.yml
期望输出形态(每个文件一行 + 明细,末行合计):
Windows 提示:打印文件名用的是
path.split("/")[-1],传反斜杠路径时不会切分,会打印成完整路径;这只是显示差异,不影响修复。
| 情形 | 期望退出码 |
|---|---|
| 正常结束(含“修复 0 行”) | 0 |
| 缺少 PyYAML | 2(先打印 需要 PyYAML,在写任何文件之前退出) |
| 目标文件不存在 / 不可写 | 1(Python traceback,非自检语义) |
缺依赖时的实测形态(本机实测:当前 Python 环境未安装 PyYAML,因此无参数运行也会直接停在这一步):
退出码 2。要真正执行修复,需先 pip install PyYAML;注意:不要为了跑一次修复而盲目装库,且安装前先确认这是预期环境(本批其余 16 个工具都不需要任何第三方包)。
依赖与权限¶
- 语言/版本:Python 3。
- 第三方依赖:PyYAML(
import yaml)—— 本批 17 个工具中唯一带非标准库依赖的工具;缺失时守卫式退出码为2。 - 仓库依赖:无(文件由命令行给出;不给参数则什么都不做)。
- 权限:不需要 root;但需要对目标 YAML 有写权限(原地改写)。
风险与注意事项¶
- 会改文件(原地写):这是本批工具里少数会改动源码树文件的工具。传入路径即被写入,不做备份、无
--dry-run、无 diff 文件输出。 - 换行会被归一化:写回固定
newline="\n",原本 CRLF 的文件会整体变成 LF,可能造成比预期更大的 diff。 - 只覆盖列表项形式:
- "..."之外的双引号标量(如key: "...")不修;fix-lib-yaml.py不能替代全库yaml.safe_load复验。 - 修复规则是“把反斜杠当字面量”,若原意确实是 YAML 转义(
\n、\t、\"),该行的解析失败原因不同,通常不会被误改(能解析成功的行一律不动)。 - 三库 YAML 属于线上平台读取的特征库数据:本工具只改仓库里的源文件,不会推送/生效到服务器;生效仍需走正常发布与
/libs/apply流程。
回滚¶
本工具不部署到线上、不改线上系统;它的“产物”就是被改写的 YAML 文件本身。
- 变更点:命令行传入的每个 YAML 文件(原地覆盖写)。
- 清理/恢复方式:用运行前的备份覆盖回去:
- 除此之外无临时目录、无缓存、无状态文件;删除
.bak备份即完成清理。