Files
sap-cli-skill/docs/guide.md
T
吴让宇 c5905a5b1e refactor: 本仓升为唯一源(原 sap-cli 源码仓归档)
方向反转:此前 SKILL.md 是「模板渲染产物」、sap-cli 是源;现 sap-cli 归档,
sap-cli-skill 承接开发与分发,SKILL.md 回归手工维护的正本。

迁移(来自 sap-cli,共 104 文件):
- tests/           692 例测试(15 个文件的内联 sys.path 改指 assets/)
- openspec/        SDD 规格与归档变更(42 文件)
- docs/            开发文档与 ADT 原理(含 dev/CLAUDE.md、AGENTS.md)
- .claude/         rules 副本 + settings.json(供 Claude Code)
- .github/ .hermes/ .pre-commit-config.yaml .editorconfig CLAUDE.md
- scripts/ 保持仅 setup.py(pack_skill.py 已随旧仓归档,不迁)

修复(迁移暴露的真实缺陷):
- assets/pyproject.toml 的 build-backend 写作 `setuptools.backends._legacy:_Backend`,
  该模块在 setuptools 中不存在 → `pip install -e` 从来装不上。改为 build_meta。
  实测:临时 venv 安装成功,sap-cli --help 正常列出 31 个命令
- pyproject readme 指向不存在的 assets/README.md(editable 安装会失败)→ 改内联文本
- pyproject urls 改指 sap-cli-skill

机制调整:
- .github/workflows/ci.yml 适配 assets/ 布局;顶部注明该工作流仅 GitHub 执行,
  本仓在 Gitee 不会自动跑
- pre-commit 增本地测试门禁(Gitee 上真正生效的那道)
- .gitignore 合并旧仓完整规则(保留 log/ 下 md 知识库入库,只忽略运行日志)
- 大文件上限 100KB→1MB(架构图 512KB)

守卫测试 tests/unit/test_repo_guards.py(10 → 18 例):
- SKILL.md 须记录 parser 全部 CLI 命令 / 铁律 1-5 须为真实小节标题 / 示例不得违反铁律 5
- references/ 规则齐备;.claude/rules 与 references 必须一致(实测抓到一次真实漂移)
- VERSION == sapcli.__version__ == README 版本
- 仓内不得再出现 pack_skill.py / skill-src(防废弃流程回潮)

698 tests OK;editable 安装与 CLI 入口经临时 venv 实测通过。
docs/RELEASING.md 重写为单源开发流程。
2026-09-11 00:40:15 +08:00

24 KiB
Raw Blame History

title, created, updated, tags, parent
title created updated tags parent
ADT 工具集使用指南 2026-05-20 2026-05-20
SAP
ADT
REST
python
tools
sap-cli/README

ADT 工具集使用指南 — main.py

[!abstract] 概述 main.py 是一个基于 SAP ADT REST API 的命令行工具,支持 reportclassfunctionfunctiongroupinterfacedomaindataelementtabletabletype 等 ABAP 开发对象的创建、信息查询、源代码下载、同步激活和删除操作。

[!info] 快速查阅 命令格式: python main.py <命令> --name <名称> --type <类型> [参数]

命令 功能 完整参数
create 创建对象 --name --type [--description] [--source] [--corr_nr]
info 查询元数据(状态/描述/时间) --name --type
download 下载源码到本地 .abap --name --type --path <目录>
sync 上传源码 → 语法检查 → 激活 --name --type --path <.abap文件> [--corr_nr]
delete 删除对象(需确认) --name --type

对象类型: report class function functiongroup interface domain dataelement table tabletype

sync 流程: 登录 → 检查/创建对象 → 锁定 → 写入 → 解锁 → 语法检查 → 激活 → 报错则退出(修改后重新执行)

典型用法:

python main.py create --name ZCL_MY_CLASS --type class
python main.py info   --name ZCL_MY_CLASS --type class
python main.py sync   --name ZCL_MY_CLASS --type class --path ./zcl_my_class.abap

1. 前置条件

环境要求

  • Python 3.10+
  • 依赖库:requests

安装依赖

pip install requests

连接配置

连接参数通过配置文件 config.ini 管理,位于脚本同目录下:

[SAP]
host = http://support.learningleader.com.cn:55955
client = 100
user = admin2
password = 654321
参数 说明
host SAP 服务器地址(不含 /sap/bc/adt 路径)
client SAP 客户端编号
user 登录用户名
password 登录密码

[!tip] 配置文件加载顺序 脚本按以下顺序查找配置:

  1. --config 参数指定的文件路径
  2. 环境变量 SAP_HOST / SAP_CLIENT / SAP_USER / SAP_PASSWORD(优先级高于配置文件)
  3. 当前工作目录下的 config.ini
  4. 脚本同目录下的 config.ini

2. 对象类型说明

工具支持以下 ABAP 开发对象类型:

类型参数 对象 SAP GUI 事务码 名称格式 支持的操作
report 程序 / 报表 SE38 / SA38 直接使用程序名 创建、查询、下载、同步、删除
class 类 (ABAP Class) SE24 直接使用类名 创建、查询、下载、同步、删除
function 函数模块 (Function Module) SE37 函数组名/函数模块名 创建、查询、下载、同步、删除
functiongroup 函数组 (Function Group) SE37 / SE80 直接使用函数组名 创建、查询、删除
interface 接口 (ABAP Interface) SE24 直接使用接口名 创建、查询、下载、同步、删除
domain 域 (Domain) SE11 直接使用域名 创建、同步
dataelement 数据元素 (Data Element) SE11 直接使用元素名 创建、同步
table 透明表 (Table) SE11 直接使用表名 创建、同步
tabletype 表类型 (Table Type) SE11 直接使用类型名 创建、查询 ²

[!warning] function 类型的名称格式 function 类型必须使用 函数组名/函数模块名 格式,用 / 分隔。例如:ZGROUP/Z_MY_FUNC

report、class 和 functiongroup 类型直接使用对象名称即可。

3. 命令一览

python main.py <命令> --name <对象名称> --type <对象类型> [其他参数]
命令 功能 必需参数
create 在 SAP 系统创建开发对象 --name, --type
info 查询对象元数据(描述、激活状态等) --name, --type
download 从 SAP 下载源代码到本地 --name, --type, --path
sync 上传本地代码到 SAP,语法检查并激活 --name, --type, --path
delete 从 SAP 系统删除对象 --name, --type

4. 功能详解

4.1 创建开发对象 (create)

在 SAP 系统中创建新的开发对象。自动生成默认源代码模板并激活。

执行流程

登录 → 检查对象不存在?
        ├─ 已存在 → 报错停止
        └─ 不存在 → 继续
      选择传输请求(交互式)
        ├─ 使用已有请求号(用户输入编号)
        ├─ 新建请求号(用户提供描述)
        └─ 不使用请求号(本地对象)
      创建对象 → 写入源代码 → 激活

命令格式

python main.py create --name <对象名> --type <类型> [--description <描述>] [--source <源代码文件>] [--corr_nr <传输请求号>]

参数说明

参数 必需 说明
--name 对象名称(function 类型用 组名/模块名
--type 对象类型:report / class / function / functiongroup
--description 对象描述,默认使用对象名称
--source 源代码文件路径(.abap),不指定则使用内置默认模板
--corr_nr 直接指定传输请求号(跳过交互选择)

示例

# 创建程序(交互式选择传输请求)
python main.py create --name ZMY_REPORT --type report --description "我的报表程序"

# 创建程序(直接指定传输请求号,跳过交互)
python main.py create --name ZMY_REPORT --type report --description "我的报表程序" --corr_nr DEVK901362

# 创建类(使用默认模板)
python main.py create --name ZCL_MY_CLASS --type class --description "我的类"

# 创建函数组
python main.py create --name ZMY_FGROUP --type functiongroup --description "我的函数组"

# 创建函数模块(自动检测并创建函数组)
python main.py create --name ZMY_FGROUP/ZMY_FUNC --type function --description "我的函数模块"

# 使用自定义源代码创建程序
python main.py create --name ZMY_REPORT --type report --source ./my_code.abap

输出示例

============================================================
  SAP ADT 创建开发对象
============================================================
  对象类型: 程序(REPORT)
  对象名称: ZMY_REPORT
  描述: 我的报表程序

  → 检查对象是否存在...
  ✓ 对象不存在,可以创建

  → 查询可用的传输请求...
  找到 2 个可修改的传输请求:

    1. DEVK901362  Implement sales validation  (所有者: ADMIN2)
    2. DEVK901365  Bugfix for invoice printing  (所有者: ADMIN2)
    3. 新建传输请求
    0. 不使用传输请求(本地对象)

  请选择 [0-3]: 1
  ✓ 已选择传输请求: DEVK901362

  → 正在创建对象...
  ✓ 对象创建成功!
  ✓ URI: /sap/bc/adt/programs/programs/zmy_report
  ✓ 源代码已写入并激活 (52 字符)

  ✓ ZMY_REPORT 创建完成!
     类型: 程序(REPORT)
     描述: 我的报表程序

[!tip] 传输请求选择 创建对象时,脚本会列出所有可修改(Modifiable)状态的传输请求供选择。

  • 选择已有请求:直接输入编号
  • 新建请求:选择"新建传输请求",然后输入描述
  • 本地对象:选择"不使用传输请求",对象将创建在 $TMP 包中
  • 非交互模式:使用 --corr_nr 参数直接指定传输请求号

默认源代码模板

不指定 --source 时,使用以下内置模板:

report 模板:

REPORT ZMY_REPORT.
WRITE: / 'Hello from ZMY_REPORT'.

class 模板:

CLASS ZCL_MY_CLASS DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC.
  PUBLIC SECTION.
    METHODS: hello.
ENDCLASS.
CLASS ZCL_MY_CLASS IMPLEMENTATION.
  METHOD hello.
  ENDMETHOD.
ENDCLASS.

function 模板:

FUNCTION ZMY_FUNC
  EXPORTING
    VALUE(EV_RESULT) TYPE STRING.
  ev_result = 'hello'.
ENDFUNCTION.

[!tip] 创建函数模块时自动创建函数组 创建 function 类型时,脚本会自动检查函数组是否存在。如果不存在,会先自动创建函数组,再创建函数模块。


4.2 源代码下载 (download)

从 SAP 系统下载对象的源代码,保存为本地 .abap 文件。

执行流程

登录 → 检查对象存在 → 获取源代码 → 保存为 .abap 文件

命令格式

python main.py download --name <对象名> --type <类型> --path <保存目录>

示例

# 下载 report
python main.py download --name ZIDTR_IMPORT_ACCOUNTING_ORDER --type report --path ./output

# 下载 class
python main.py download --name ZCL_MY_CLASS --type class --path ./output

# 下载 function
python main.py download --name ZGROUP/Z_MY_FUNC --type function --path ./output

输出

  • --path 指定目录下生成 同名小写.abap 文件
  • 例如:--name ZMY_REPORT./output/zmy_report.abap
  • 如果保存目录不存在,会自动创建

输出示例

============================================================
  SAP ADT 源代码下载
============================================================
  对象类型: 程序(REPORT)
  对象名称: ZIDTR_IMPORT_ACCOUNTING_ORDER
  保存路径: ./output

  → 正在登录...
  ✓ 登录成功

  → 检查对象是否存在...
  ✓ 对象存在

  → 正在下载源代码...
  ✓ 源代码下载成功! 37655 字符, 1096 行

  ✓ 文件已保存: ./output\zidtr_import_accounting_order.abap

  ✅ 下载完成!
     文件: ./output\zidtr_import_accounting_order.abap
     大小: 37655 字符, 1096 行

4.3 源代码同步激活 (sync)

将本地 .abap 文件的代码上传到 SAP 系统,进行语法检查并激活。报错时直接退出,由调用者修改代码后重新执行

执行流程

登录 → 检查对象是否存在?
        ├─ 不存在 → 自动创建空对象 → 继续
        └─ 存在 → 继续
      锁定对象(自动检测传输请求绑定)
        ├─ 对象已绑定请求号 → 自动使用原请求号
        ├─ 本地对象($TMP)→ 无需请求号
        └─ 需要请求号但未绑定 → 交互选择(已有/新建)
      写入 → 解锁
      → 语法检查
        ├─ 有错误 → 输出错误信息 → 退出(exit code 1)
        └─ 无错误 → 继续
      → 激活
        ├─ 成功 → 输出成功信息 → 退出(exit code 0)
        └─ 失败 → 输出错误信息 → 退出(exit code 1

[!important] 非交互式设计 脚本发现语法错误或激活失败时,不会暂停等待用户输入,而是直接输出错误信息并以 exit code 1 退出。 调用者需要根据错误信息修改本地 .abap 文件,然后重新执行 sync 命令。

[!tip] 传输请求自动检测 sync 命令会先尝试锁定对象,通过 SAP 系统返回的信息自动判断传输请求绑定状态:

  • 如果对象已绑定到某个请求号 → 直接使用该请求号,无需用户干预
  • 如果对象是本地对象($TMP)→ 不需要请求号
  • 只有当对象需要请求号但尚未绑定时,才会提示用户选择或新建请求号

命令格式

python main.py sync --name <对象名> --type <类型> --path <.abap文件路径> [--corr_nr <传输请求号>]

参数说明

参数 必需 说明
--name 对象名称(function 类型用 组名/模块名
--type 对象类型
--path 本地源代码文件路径(.abap
--corr_nr 直接指定传输请求号(跳过自动检测)

示例

# 同步激活 report(自动检测传输请求绑定)
python main.py sync --name ZIDTR_IMPORT_ACCOUNTING_ORDER --type report --path ./zidtr_import_accounting_order.abap

# 同步激活 report(直接指定传输请求号)
python main.py sync --name ZIDTR_IMPORT_ACCOUNTING_ORDER --type report --path ./zidtr_import_accounting_order.abap --corr_nr DEVK901362

# 同步激活 class
python main.py sync --name ZCL_MY_CLASS --type class --path ./zcl_my_class.abap

# 同步激活 function
python main.py sync --name ZGROUP/Z_MY_FUNC --type function --path ./z_my_func.abap

输出示例 — 成功(对象已绑定请求号)

============================================================
  SAP ADT 源代码同步激活
============================================================
  对象类型: 类(CLASS)
  对象名称: ZCL_MY_CLASS
  本地文件: ./zcl_my_class.abap
  源代码: 256 字符, 12 行
  流程: 检查/创建 → 写入 → 语法检查 → 激活

  → 检查对象是否存在...
  ✓ 对象存在

────────────────────────────────────────────────────────────

  ── Step 1/4: 锁定 → 写入 → 解锁 ──
  ✓ 锁定成功(对象已绑定传输请求: DEVK901362)
  ✓ 源代码写入成功
  ✓ 解锁成功

  ── Step 2/4: 语法检查 ──
  ✓ 语法检查通过

  ── Step 3/4: 激活对象 ──
  ✓ 激活成功!

  ============================================================
  ✓ ZCL_MY_CLASS 已成功同步并激活!
  ============================================================

输出示例 — 对象未绑定请求号(需要选择)

  ── Step 1/4: 锁定 → 写入 → 解锁 ──
  ℹ 对象需要传输请求号

  → 查询可用的传输请求...
  找到 2 个可修改的传输请求:

    1. DEVK901362  Implement sales validation  (所有者: ADMIN2)
    2. DEVK901365  Bugfix for invoice printing  (所有者: ADMIN2)
    3. 新建传输请求
    0. 不使用传输请求(本地对象)

  请选择 [0-3]: 1
  ✓ 已选择传输请求: DEVK901362
  ✓ 锁定成功(传输请求: DEVK901362)
  ✓ 源代码写入成功
  ✓ 解锁成功

── Step 1/4: 锁定 → 写入 → 解锁 ── ✓ 锁定成功 ✓ 源代码写入成功 ✓ 解锁成功

── Step 2/4: 语法检查 ── ✓ 语法检查通过

── Step 3/4: 激活对象 ── ✓ 激活成功!

============================================================ ✓ ZCL_MY_CLASS 已成功同步并激活!


#### 输出示例 — 语法检查失败

── Step 2/4: 语法检查 ── ✗ 语法检查未通过! 2 个错误, 1 个警告: [错误] 行 10: Field "XXX" is unknown [错误] 行 25: Type "ZZZ" is unknown [警告] 行 5: Unused variable "LV_TEST"

请修改本地文件后重新执行: ./zmy_report.abap


> [!tip] 对象不存在时自动创建
> 当同步的目标对象在 SAP 系统中不存在时,脚本会自动创建一个空对象,然后继续执行写入和激活流程。
> 如果自动创建失败,会输出错误信息并退出,此时需要先使用 `create` 命令手动创建。

---

### 4.4 对象信息查询 (`info`)

查询 SAP 系统中开发对象的元数据信息,包括描述、激活状态、开发包、传输请求号、负责人、修改时间等。

#### 执行流程

登录 → 查询对象元数据 → 输出信息


#### 命令格式

```bash
python main.py info --name <对象名> --type <类型>

示例

# 查询类信息
python main.py info --name ZCL_MY_CLASS --type class

# 查询程序信息
python main.py info --name ZMY_REPORT --type report

# 查询接口信息
python main.py info --name ZIF_MY_INTERFACE --type interface

输出示例

============================================================
  SAP ADT 对象信息查询
============================================================
  对象类型: 类(CLASS)
  对象名称: ZCL_MY_CLASS

  → 正在登录...
  ✓ 登录成功

  → 正在查询对象信息...
  ✓ 查询成功

  ──────────────────────────────────────────────────
  名称:     ZCL_MY_CLASS
  类型:     CLAS/OC
  描述:     My ABAP Class
  状态:     ✅ 已激活
  负责人:   ADMIN2
  语言:     ZH
  开发包:   ZSAPILOT
  传输请求: DEVK901362
  创建者:   ADMIN2
  修改者:   ADMIN2
  修改时间: 2026-05-20T12:00:00Z
  URI:      /sap/bc/adt/oo/classes/zcl_my_class
  ──────────────────────────────────────────────────

[!tip] 状态说明

  • ✅ 已激活 — 对象处于 active 状态,可在系统中正常使用
  • ⚠️ 未激活 — 对象有未激活的更改,需要执行 sync 激活后才能生效

[!note] 开发包与传输请求

  • 开发包 —— 直接从对象元数据读取
  • 传输请求 —— 纯只读查询系统表 E071,显示对象当前所在的未释放请求(多个用逗号分隔)
    • —— 对象不在任何未释放请求中
    • (无法获取) —— 无系统表查询权限或查询失败(不影响其余字段输出)
    • —(非独立传输对象) —— include / function 等非独立 R3TR 对象,不单独占用传输请求

[!note] 支持的对象类型 info 命令支持全部 9 种对象类型:reportclassfunctionfunctiongroupinterfacedomaindataelementtabletabletypetabletype 通过 VIT 端点/sap/bc/adt/vit/wb/object_type/ttypda/object_name/{name})访问,仅支持元数据查询(info),不支持源码读写(download/sync)和删除操作。


4.5 源代码删除 (delete)

从 SAP 系统中删除指定的开发对象。删除前需要交互确认

执行流程

登录 → 检查对象存在 → 确认删除 → 查询传输请求 → 锁定 → 执行删除

命令格式

python main.py delete --name <对象名> --type <类型>

示例

# 删除 report
python main.py delete --name ZMY_OLD_REPORT --type report

# 删除 class
python main.py delete --name ZCL_OBSOLETE --type class

# 删除 function
python main.py delete --name ZGROUP/Z_OLD_FUNC --type function

确认提示

  ⚠️  即将从 SAP 系统中删除: ZMY_OLD_REPORT
  类型: 程序(REPORT)
  URI: /sap/bc/adt/programs/programs/zmy_old_report

  确认删除? (输入 yes 确认):

[!danger] 不可逆操作 删除操作不可恢复!请确认对象名称无误后再输入 yes。输入其他任何内容均取消操作。

5. API 端点映射

不同对象类型对应的 ADT REST API 路径:

对象类型 对象 URI 源代码 URI
report /sap/bc/adt/programs/programs/{name} .../source/main
class /sap/bc/adt/oo/classes/{name} .../source/main
interface /sap/bc/adt/oo/interfaces/{name} .../source/main
function /sap/bc/adt/functions/groups/{group}/fmodules/{name} .../source/main
functiongroup /sap/bc/adt/functions/groups/{name}
domain /sap/bc/adt/ddic/domains/{name} .../source/main
dataelement /sap/bc/adt/ddic/dataelements/{name} .../source/main
table /sap/bc/adt/ddic/tables/{name} .../source/main
tabletype /sap/bc/adt/vit/wb/object_type/ttypda/object_name/{name} — (VIT 端点,仅元数据)

[!note] URL 中的名称使用小写 SAP ADT API 的 URL 路径中对象名称通常使用小写形式。tabletype 例外 — VIT 端点使用大写名称以获取完整元数据。脚本已自动处理大小写转换,--name 参数输入原始大小写即可。

6. 典型工作流

场景一:创建新对象 → 修改 → 同步激活

# Step 1: 创建新程序(自动生成默认代码并激活)
python main.py create --name ZMY_REPORT --type report --description "我的报表"

# Step 2: 下载到本地编辑
python main.py download --name ZMY_REPORT --type report --path ./src

# Step 3: 用编辑器修改 ./src/zmy_report.abap

# Step 4: 同步激活
python main.py sync --name ZMY_REPORT --type report --path ./src/zmy_report.abap

场景二:下载 → 修改 → 同步激活

# Step 1: 下载已有对象源代码
python main.py download --name ZMY_REPORT --type report --path ./src

# Step 2: 用编辑器修改 ./src/zmy_report.abap

# Step 3: 同步激活(如果激活失败,修改后重试)
python main.py sync --name ZMY_REPORT --type report --path ./src/zmy_report.abap

场景三:函数模块开发

# 创建函数组(如果不存在)
python main.py create --name ZMY_FGROUP --type functiongroup --description "我的函数组"

# 创建函数模块(自动检测函数组,不存在则自动创建)
python main.py create --name ZMY_FGROUP/ZMY_FUNC --type function --description "我的函数"

# 下载并修改
python main.py download --name ZMY_FGROUP/ZMY_FUNC --type function --path ./src

# 同步激活
python main.py sync --name ZMY_FGROUP/ZMY_FUNC --type function --path ./src/zmy_func.abap

场景四:清理废弃对象

# 删除废弃程序
python main.py delete --name ZOLD_REPORT --type report

# 删除废弃类
python main.py delete --name ZCL_OBSOLETE --type class

# 删除废弃函数模块
python main.py delete --name ZMY_FGROUP/ZOLD_FUNC --type function

7. 日志系统

所有 API 请求和响应详细记录在日志文件中:

sap-cli/adt_tools.log

日志内容示例

2026-05-20 10:30:00 | INFO    | LOGIN: GET http://.../compatibility/graph
2026-05-20 10:30:00 | INFO    | LOGIN RESPONSE: HTTP 200
2026-05-20 10:30:00 | INFO    | CSRF Token: abCdEfGhIjKlMnOpQrSt...
2026-05-20 10:30:01 | INFO    | GET SOURCE: GET .../source/main
2026-05-20 10:30:01 | INFO    | GET SOURCE RESPONSE: HTTP 200, 37655 bytes
2026-05-20 10:30:02 | INFO    | LOCK: POST .../programs/zmy_report (corrNr=DEVK901362)
2026-05-20 10:30:02 | INFO    | LOCK RESPONSE: HTTP 200
2026-05-20 10:30:03 | INFO    | SET SOURCE: PUT .../source/main (1024 chars)
2026-05-20 10:30:03 | INFO    | ACTIVATE: POST .../activation name=ZMY_REPORT
2026-05-20 10:30:03 | INFO    | Activation msg [E] line=10: Field "XXX" unknown
2026-05-20 10:30:03 | INFO    | Activation result: FAILED (1 errors)

排查问题

  1. 查看 adt_tools.log 中的错误信息
  2. 搜索 FAILEDERROR 关键字
  3. 激活错误中 line 为语句序号,href 中的 start=XXX 为字符偏移量
  4. 结合源代码定位问题位置

8. 常见问题

问题 原因 解决方案
登录失败 HTTP 401 用户名或密码错误 检查 config.ini 中的连接配置
对象不存在 HTTP 404 名称或类型错误 确认 --name--type 参数
对象已存在 HTTP 403 创建时对象名冲突 使用不存在的对象名或先删除已有对象
锁定失败 对象被其他用户锁定 脚本自动处理 corrNr 冲突;如仍失败,等待或联系管理员
未找到传输请求 系统中无 Modifiable 状态的 TR 在 SAP 中创建传输请求 (SE01/SE09)
激活报语法错误 代码有语法问题 修改本地文件后重新执行 sync 命令
删除失败 权限不足或对象被锁定 检查 S_DEVELOP 权限
环境变量覆盖配置 系统环境变量 SAP_HOST 已设置 运行前清除:$env:SAP_HOST=""

9. 相关笔记