Shell 内嵌 Python 片段 import 自检(scan-py-snippets.py)¶
位置:
deploy/nfos/tools/scan-py-snippets.py| 语言:python3 | 是否需要 root:否
工具性质:离线静态自检(只读源码,不写任何文件)
运行前提:仓库检出在场即可;本工具不自动定位仓库根,路径按当前工作目录解析
部署状态:随仓库检出运行,不部署到 /opt/Cy/services/system.d/nfos/
用途¶
deploy/nfos/security-guard.sh 里有十几处 python3 -c '...' 与 python3 - <<'PY' 形式的内嵌 Python 片段。片段里一旦用了 os.environ 却忘了 import os,运行期就是 NameError:
- 守卫会静默走 WARN 分支(“推送参数解析失败”)→ 告警推不到人;
bash -n完全看不出来(那是 shell 语法检查,不看片段内部)。
本工具把 shell 脚本里的 Python 片段抽取出来,用 ast 解析,找出「被读取(ast.Load)但既不是内建、也没在片段里赋值/导入/定义」的名字,逐个片段打印结果:
| 输出行 | 含义 |
|---|---|
ok L<n>(python3 -c) / ok L<n>(heredoc) |
片段内无缺失 import |
!! L<n>(...) 缺 import:os(L42) |
该片段缺 stdlib import(计入结论) |
?? L<n>(...) 无法解析:SyntaxError: ... |
片段解析失败(不计入结论,也不改变退出码) |
末尾固定打印一行结论:结论:<N> 个片段缺 stdlib import(文件 <path>)。
识别范围的重要边界:只有当缺失的名字落在源码内 STDLIB 白名单(23 个常用标准库名,如 os/sys/json/re/time/socket/subprocess/hashlib/ipaddress 等)时才会被报出;第三方库名不在白名单,不会被检出。
典型场景¶
- 改完
security-guard.sh(新增/修改python3 -c或 heredoc 片段)后,在提交前跑一遍,确认没有漏import; - 巡检脚本“改了却没有任何告警推送”时,作为
NameError类静默失败的第一道排查手段; - 批量迁移守卫脚本里内嵌片段时,作为机械化的回归检查。
用法与参数¶
源码 docstring 给出的用法(逐字引用,其中 .scratch/ 是升级前的旧路径):
本页统一按新位置书写为 python deploy/nfos/tools/scan-py-snippets.py <脚本>。位置参数只有一个:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
sys.argv[1] |
字符串(文件路径) | deploy/nfos/security-guard.sh |
待扫描的 shell 脚本;相对当前工作目录解析(不是相对仓库根) |
无参数时的默认行为:扫描 deploy/nfos/security-guard.sh(相对当前工作目录)。因此在仓库根目录执行时可无参数运行;在别处执行必须显式传路径。
示例¶
在仓库根目录执行(自检类工具的推荐用法——从任何位置都能运行,但仓库检出必须在场):
期望输出形态:
| 情形 | 期望退出码 |
|---|---|
| 全部片段通过 | 0 |
| 至少 1 个片段缺 stdlib import | 1 |
| 目标文件不存在 / 不可读(异常未捕获) | 1(Python traceback,非自检语义) |
依赖与权限¶
- 语言/版本:Python 3.7+(源码含
from __future__ import annotations)。 - 第三方依赖:无,仅标准库
ast/builtins/re/sys。 - 仓库依赖:无(不给路径时不读仓库任何固定文件;给相对路径则依赖当前工作目录)。
- 权限:不需要 root,不需要写权限(纯只读)。
风险与注意事项¶
- 纯离线只读:只
open(<path>)读取目标脚本,不写文件、不联网、不执行被扫描的片段(只用ast.parse解析,不eval/exec)。 - 不是完备的 lint:只覆盖
STDLIB白名单里的名字;json、os之外的自定义名或第三方名缺失不会报。 ??(无法解析)的片段被跳过,不计入bad,因此片段被误抽取(例如引号嵌套导致截断)可能表现为“全 ok”的假通过——出现??行时要人工看一眼。- 抽取逻辑是行级启发式(匹配
python3+-c '或python3+- <<'TAG'),非常规写法(如python -c、变量拼接、<<-缩进 heredoc)不会被抽取。
回滚¶
本工具不部署到线上、不改线上系统。它不产生任何产物:
- 无输出文件、无临时目录、无状态文件;
- 不改动被扫描的 shell 脚本(只读打开);
- 无需清理。若只是跑过本工具,
git/文件系统的比对结果应当为空。