Repository navigation
KShell 2.1.0 版本文档
版本:2.1.0(代号 Plugin)
发布日期:2026-10-04
开源协议:Apache License 2.0
支持平台:Windows 10/11 · macOS 10.15+ · Linux(主流发行版)
运行环境:Python 3.6+(核心零第三方依赖)
目录
一、版本概览
KShell 2.1 的核心是插件系统:用「JSON 配置 + Python 实现」扩展终端,无需修改 KShell 本体。
配套地,官网新增开发者社区子路由与后台插件注册表管理。
| 项目 | 2.0.0 | 2.1.0 |
|---|---|---|
| 内置命令数量 | 68 | 69 |
| 扩展方式 | 修改源码 | 插件目录(免改源码) |
| 插件系统 | 无 | JSON 声明 + Python 实现 + 热重载 |
| 插件脚手架 | 无 | plugin new 自动生成 |
| 插件配置 | 无 | plugin config 持久化,支持类型推断 |
| 插件隔离 | 无 | 加载/执行异常均被隔离 |
| 开发者文档 | 无 | PLUGIN_DEV.md + 社区页面 |
| 官网子路由 | 单页 | /community 开发者社区 |
| 后台功能 | 5 个视图 | 6 个视图(新增插件社区) |
| 打包体积 | 7.9 MB | 约 12 MB(含插件标准库) |
二、版本亮点
- 插件 = 2 个文件 —
plugin.json(元数据+配置)+plugin.py(实现),放进plugins/即被自动发现。 - 热重载 —
plugin reload立即生效,改代码无需重启 KShell。 - 异常隔离 — 插件加载失败或执行出错只提示,不会拖垮 Shell。
- 脚手架 —
plugin new myplugin一键生成可运行的插件骨架。 - 配置系统 — 插件在
plugin.json声明配置项,用户用plugin config覆盖并持久化。 - 开发者社区 — 官网
/community,含完整开发文档、示例源码与插件画廊。 - 后台插件管理 — 可视化增删改插件条目、控制发布状态与推荐置顶。
三、插件系统
3.1 插件结构
plugins/
└── myplugin/
├── plugin.json 元数据、命令声明、默认配置
└── plugin.py Python 实现
搜索目录(优先级从高到低,同名插件不被低优先级覆盖):
| 顺序 | 目录 | 说明 |
|---|---|---|
| 1 | sys._MEIPASS/plugins |
打包内置(官方示例) |
| 2 | 项目根 plugins/ |
源码运行 |
| 3 | 可执行文件同级 plugins/ |
用户插件推荐位置 |
| 4 | ~/.kshell/plugins |
用户级 |
| 5 | 配置 plugins.dirs |
自定义目录 |
3.2 plugin.json
{
"name": "myplugin",
"version": "1.0.0",
"author": "你的名字",
"description": "插件说明",
"homepage": "https://github.com/you/myplugin",
"kshell": ">=2.1.0",
"enabled": true,
"commands": {
"myplugin": {
"function": "cmd_main",
"usage": "myplugin [参数] [-v]",
"description": "命令说明",
"aliases": ["mp"]
}
},
"settings": {
"greeting": "Hello"
}
}commands 支持三种写法:
- 字符串数组 —
["hello", "greet"],函数名约定为cmd_<命令名> - 对象 — 可指定
function/usage/description/aliases - 省略 — 自动扫描
plugin.py中所有cmd_*函数(cmd_auto_one→ 命令auto-one)
manifest 校验(不通过则只报错,不影响 KShell):
| 校验项 | 说明 |
|---|---|
| JSON 语法 | 解析失败直接报错 |
name 必填且合法 |
只允许字母、数字、_、- |
name 与目录名一致 |
不一致时报错 |
commands 格式 |
必须是数组或对象 |
| 函数存在性 | 声明的函数必须在 plugin.py 中可调用 |
| 版本要求 | kshell 字段与当前版本比对 |
settings 类型 |
必须是 JSON 对象 |
3.3 plugin.py 与 ctx API
def cmd_hello(args, options, ctx):
greeting = ctx.get('greeting', 'Hello') # 读插件配置
name = args[0] if args else 'World'
return 0, f'{greeting}, {name}!' # (退出码, 输出)ctx 提供:
| 成员 | 说明 |
|---|---|
ctx.name / ctx.version / ctx.dir |
插件元信息 |
ctx.get(k, d) / ctx.set(k, v) / ctx.config() |
插件配置读写 |
ctx.fs / ctx.platform / ctx.settings / ctx.theme |
KShell 能力 |
ctx.colorize(text, key) |
主题着色 |
ctx.log(msg) |
日志(加载阶段打印) |
ctx.register_command(...) |
运行期动态注册命令 |
返回值归一化:(code, str) / str / None / int 都能正确处理。
可选回调:on_load(ctx) / on_unload(ctx)。
3.4 加载机制
- 动态编译:读取源码后
compile()+exec(),不使用 importlib 的字节码缓存- 原因:CPython 的
.pyc过期判断依赖「源文件 mtime(秒级)+ 文件大小」,同秒内改动等长代码会命中旧字节码,导致热重载失效 - 附带好处:不会在用户的插件目录里生成
__pycache__
- 原因:CPython 的
- 异常隔离:导入异常 → 记录
load_error;执行异常 → 返回(1, 错误信息) - 配置持久化:
plugins.enabled/plugins.config/plugins.dirs写入kshell_config.json - 目录可写性检测:
plugin new会实测目录可写,且排除打包临时目录(_MEIPASS退出即删)
3.5 官方示例插件
| 插件 | 命令 | 演示内容 |
|---|---|---|
hello |
hello greet |
配置读取、选项解析、返回值、on_load 回调、别名 |
pwgen |
pwgen uuid passwd-strength |
多命令插件、命令名与函数名不同、secrets 加密安全随机 |
sysinfo |
sysinfo sys |
--json 结构化输出、配置开关、优雅降级 |
四、plugin 命令
plugin # 列出全部插件
plugin list # 同上
plugin info <名称> # 详情:元数据、命令、配置、失败原因
plugin enable <名称> # 启用(写入配置)
plugin disable <名称> # 禁用(写入配置)
plugin reload [名称] # 重新加载(省略名称则全部)
plugin config <名称> # 查看插件配置
plugin config <名称> k=v # 修改插件配置(自动推断类型)
plugin dirs # 显示插件搜索目录
plugin new <名称> # 生成插件骨架
plugin help # 子命令帮助配置值类型推断:true/false → 布尔,123 → 整数,1.5 → 浮点,null → None,其余为字符串。
示例:
$ plugin new myplugin
插件骨架已生成: D:\KShell\plugins\myplugin
$ plugin reload myplugin
插件 myplugin 已重新加载(1 条命令)
$ plugin config myplugin greeting=你好
已更新插件 myplugin 的配置: greeting
$ plugin list
KShell 插件(4 个)
名称 版本 状态 命令数 说明
hello 1.0.0 已加载 2 最小示例插件…
myplugin 0.1.0 已加载 1 myplugin 插件
pwgen 1.0.0 已加载 3 密码与 UUID 生成器…
sysinfo 1.0.0 已加载 2 系统信息速查…
已加载 4 · 禁用 0 · 失败 0 · 注册命令 8 条五、开发者社区
5.1 官网子路由 /community
面向插件开发者的文档页,包含:
- 30 秒上手 —— 脚手架命令演示
- 插件结构 —— 目录约定与搜索优先级
- plugin.json 字段 —— 完整字段表 + 三种 commands 写法
- plugin.py 实现 —— 函数签名、选项解析注意点
- ctx 上下文 API —— 全部成员与着色 key
- 返回值约定 —— 四种返回形式与异常隔离行为
- 官方示例插件 —— 三个插件的真实源码(选项卡切换)
- 插件画廊 —— 从
/api/plugins动态加载,支持标签筛选 - 提交你的插件 —— 步骤与发布前自查清单
- 安全须知 —— 权限模型与注意事项
页面自带侧栏目录(滚动高亮)、代码复制按钮、移动端适配。
5.2 后台插件管理
后台新增「插件社区」视图:
| 功能 | 说明 |
|---|---|
| 注册表统计 | 条目总数、已发布、官方、推荐位、标签汇总 |
| 新增/编辑 | 表单包含名称、版本、作者、说明、仓库、命令、标签 |
| 发布控制 | 未发布的条目只在后台可见,不出现在前台 |
| 推荐置顶 | 标记推荐后在前台画廊中优先排序 |
| 官方标记 | 显示「官方」徽章 |
| 删除 | 二次确认 |
| 补回官方示例 | 幂等操作,仅补齐缺失的内置条目 |
字段校验(服务端白名单):
| 字段 | 规则 |
|---|---|
name |
必填,仅字母数字下划线连字符,最长 60 |
version |
最长 20 |
author |
最长 80 |
description |
最长 400 |
repo / homepage |
必须是 http(s) 链接 |
commands |
最多 20 项,单项最长 40(支持逗号分隔输入) |
tags |
最多 8 项,单项最长 20(支持逗号分隔输入) |
published / featured / official |
布尔 |
5.3 公开接口
| 路径 | 说明 |
|---|---|
GET /community |
开发者社区页面 |
GET /api/plugins |
已发布的插件列表 + 标签汇总(带 120 秒缓存) |
六、缺陷修复
2.1 开发过程中发现并修复的问题(多数由测试与截图验收暴露):
| # | 问题 | 影响 | 修复 |
|---|---|---|---|
| 1 | 热重载读到旧代码 | 同秒内改动等长源码时,CPython 的 .pyc 过期判断(mtime 秒级 + 文件大小)会命中缓存字节码,plugin reload 不生效 |
改为直接读取源码 compile() + exec(),绕过字节码缓存 |
| 2 | 非 GBK 字符导致 Shell 崩溃 | Windows 控制台默认 GBK,插件输出 ✓、emoji 等字符会抛 UnicodeEncodeError 并中断整个 Shell |
新增 safe_print(),所有输出走它,无法编码时降级替换 |
| 3 | 配置出现扁平重复键 | SettingsManager 只支持扁平键,plugins.config 被当成字面键名写进配置,与嵌套默认值重复 |
为 SettingsManager 实现点号路径读写(含扁平键回退兼容) |
| 4 | 打包后插件无法导入标准库 | PyInstaller 静态分析看不到动态加载插件的 import,pwgen 在 exe 中报 ModuleNotFoundError: secrets |
新增 PLUGIN_STDLIB_HINTS 清单,由 kshell.spec 导入并加入 hiddenimports |
| 5 | 打包后脚手架写入临时目录 | plugin new 把插件生成到 _MEIPASS(退出即删),用户拿不到文件 |
新增 scaffold_dir():实测可写、排除临时目录,优先可执行文件同级 |
| 6 | 插件目录生成 __pycache__ |
早期 importlib 加载会在用户插件目录留下 .pyc |
改为 compile/exec 后不再生成(已验证) |
七、命令与配置
7.1 命令数量
| 类别 | 2.0 | 2.1 |
|---|---|---|
| 核心内置 | 36 | 36 |
| 扩展命令 | 32 | 32 |
| 插件管理 | — | 1(plugin) |
| 合计 | 68 | 69 |
此外,插件会注册各自的命令(官方示例贡献 7 条)。
7.2 新增配置项
{
"plugins": {
"enabled": {}, // { "插件名": true/false }
"config": {}, // { "插件名": { "键": 值 } }
"dirs": [] // 额外插件搜索目录
}
}八、架构变化
8.1 新增模块
pluginmgr.py 插件系统核心
· PluginManager —— 发现、加载、注册、配置、脚手架
· Plugin / PluginCommand —— 插件与命令描述
· PluginContext —— 传给插件函数的上下文
· PLUGIN_STDLIB_HINTS —— 打包时需包含的插件常用标准库清单
commands_plugin.py plugin 命令组实现
version.py 版本号单一来源(VERSION / check_requirement)
plugins/ 官方示例插件
hello/ pwgen/ sysinfo/
PLUGIN_DEV.md 插件开发指南
8.2 加载流程
terminal.__init__()
│
├─ BuiltinCommands() 注册 36 核心命令
│ └─ ExtraCommands() 注册 32 扩展命令
│ └─ PluginCommands() 注册 plugin 命令
│
└─ PluginManager.load_all()
│
├─ resolve_dirs() 解析搜索目录(含 _MEIPASS / 用户目录 / 配置)
├─ find_manifests() 扫描 plugin.json
└─ load() 每个插件
├─ 解析并校验 plugin.json
├─ 版本要求比对
├─ 启用状态检查
├─ 读取源码 → compile() → exec() ← 绕过字节码缓存
├─ 包装并注册命令(异常隔离 + 返回值归一化)
└─ 调用 on_load(ctx)
8.3 命令派发顺序(未变)
command 强制系统命令 → 内置命令(含插件命令)→ 系统 PATH 命令
插件命令与内置命令同级,因此插件命令会覆盖同名内置命令——这是有意设计(方便插件扩展/覆盖行为),但插件开发者应避免与内置命令重名。
九、从 2.0 升级
9.1 兼容性
✅ 配置文件兼容 — 2.0 的 kshell_config.json 可直接使用,plugins 段会自动补齐默认值。
✅ 命令语法兼容 — 所有 2.0 命令行为不变。
✅ 脚本兼容 — .ksh 脚本无需修改。
✅ 旧版配置的扁平键兼容 — 若存在 "plugins.config" 这类扁平键,SettingsManager 读取时会回退匹配。
9.2 行为变更
| 变更 | 说明 |
|---|---|
新增 plugin 命令 |
若你之前自定义过 plugin 命令,会被覆盖 |
| 启动时扫描插件目录 | 首次启动稍慢(毫秒级);插件加载失败会在启动时提示 |
新增 plugins 配置段 |
老配置会自动补默认值 |
| 打包体积增加 | 约 7.9 MB → 12 MB,因为纳入了插件常用标准库模块 |
9.3 升级步骤
Windows
:: 备份配置
copy kshell_config.json kshell_config.json.bak
:: 用新的 exe 替换(可选:在 exe 同级建 plugins 目录放插件)
kshell_windows_x64_v2.1.exe验证
kshell # 横幅应显示 KShell v2.1
plugin list # 应列出 3 个官方示例插件
plugin help # 应输出子命令帮助
hello KShell # 应输出 Hello, KShell!十、安装方式
Windows
kshell_windows_x64_v2.1.exe :: 交互模式
kshell_windows_x64_v2.1.exe script.ksh :: 脚本模式重新构建:
packaging\build_windows.bat打包时会把
plugins/(官方示例)与PLUGIN_DEV.md一并内嵌。用户自己的插件放在 exe 同级plugins/目录 即可。
Linux
# APT 仓库
echo "deb [trusted=yes] http://39.96.82.163/apt stable main" | sudo tee /etc/apt/sources.list.d/kshell.list
sudo apt update && sudo apt install -y kshell
# 或源码
git clone https://github.com/Qin-collab/KShell.git
cd KShell && python3 kshell.py自行构建安装包:pip3 install pyinstaller && bash packaging/build_linux.sh
十一、测试与验证
| 测试套件 | 覆盖范围 | 结果 |
|---|---|---|
test_v21_plugins.py |
新增:版本比较、插件加载、manifest 校验(8 种非法情况)、命令执行、配置读写、启用禁用、热重载、异常隔离、返回值归一化、自动发现、脚手架、自定义目录、统计 | 85 项通过 / 0 失败 |
test_v2_syscmd.py |
PATH 解析、选项透传、优先级派发、command 绕过、path、calc |
27 项通过 |
test.py |
平台抽象、文件系统、命令解析、内置命令 | 通过 |
test_extra.py |
扩展命令 | 通过 |
test_v21_terminal.ksh |
端到端:12 个场景(含 3 个插件、配置修改、别名、未知插件) | 通过 |
| 打包后 exe | 插件列表、执行、脚手架、目录解析 | 通过 |
| 后台插件注册表 | CRUD、5 项校验规则、发布状态过滤、推荐置顶、幂等补种 | 通过 |
官网 /community |
渲染、画廊动态加载、标签筛选、响应式(390/768/1440) | 通过 |
验证方法说明:除单元测试外,本轮全程使用 CDP 无头浏览器截图 + 页面探针做视觉验收——缺陷 #2、#4、#5 都是靠截图与实机运行发现的,纯接口测试无法暴露。
十二、已知限制
- 插件无沙箱 — 插件是普通 Python 代码,拥有与 KShell 相同的权限。只运行可信插件。
- 插件异常隔离有边界 — 异常会被捕获,但死循环、
sys.exit()、超大内存分配仍会影响 Shell。 - 插件命令可覆盖内置命令 — 同名时插件优先;请避免与内置命令重名。
- 打包后插件依赖受限于预置标准库 — exe 已内嵌
PLUGIN_STDLIB_HINTS中的常用标准库;若插件需要第三方库(如requests),需自行重新打包或使用源码运行。 plugin enable/disable需 reload 才立即生效 — 写入配置后,运行中的命令表不会自动更新(可用plugin reload)。plugins.dirs需 JSON 数组 — 通过config set修改时需写成数组形式。- 网站后台插件注册表与本地插件目录无关联 — 注册表是「社区目录」,用于展示;不会自动安装插件。
- 插件热重载不重载其第三方依赖 — 只重新编译插件自身源码。
附录:2.1.0 变更文件清单
新增
| 文件 | 说明 |
|---|---|
pluginmgr.py |
插件系统核心 |
commands_plugin.py |
plugin 命令组 |
version.py |
版本号单一来源 |
plugins/hello/ |
示例:入门 |
plugins/pwgen/ |
示例:多命令与加密安全随机 |
plugins/sysinfo/ |
示例:结构化输出与降级 |
PLUGIN_DEV.md |
插件开发指南 |
RELEASE_2.1.0.md |
本文档 |
test_v21_plugins.py |
插件测试(85 项) |
test_v21_terminal.ksh |
插件端到端测试 |
tools/backup.ps1 |
备份脚本(含 SHA256 校验清单) |
HTML/public/community.html/css/js |
开发者社区页面 |
HTML/lib/registry.js |
后台插件注册表 |
修改
| 文件 | 主要变更 |
|---|---|
terminal.py |
创建并加载插件管理器;新增 safe_print();版本号改用 version.py |
builtin.py |
注册 plugin 命令;新增 set_plugin_manager();帮助文本更新 |
settings.py |
新增 plugins 配置段;实现点号路径读写 |
banner.py |
版本号取自 version.py |
kshell.spec |
内嵌 plugins/ 与文档;加入插件标准库 hiddenimports |
HTML/server.js |
/community 路由、/api/plugins、插件注册表后台接口 |
HTML/lib/store.js |
支持 KSH_DATA_DIR 指定数据目录(多实例/测试隔离) |
HTML/admin/* |
新增「插件社区」视图 |
HTML/public/index.html |
主导航加入开发者社区入口 |
HTML/README.md |
社区与注册表文档 |
KShell 2.1.0 — 一个用纯 Python 写的、能跑在三类系统上的轻量终端,现在你可以自己扩展它了。
关于可执行文件的数字签名
本版本的 kshell_windows_x64_v2.1.exe 已使用 Authenticode 数字签名(SHA256 + RFC3161 可信时间戳)。
| 项目 | 值 |
|---|---|
| 签名类型 | Authenticode / sha256RSA |
| 签名者 | CN=KShell, O=Qin-collab, OU=KShell Project, C=CN |
| 证书指纹 | 3F70D8564BCBD01B405E0E087E5C66A3136F61A0 |
| 时间戳 | DigiCert SHA256 RSA4096 Timestamp Responder |
| 有效期 | 2026-10-05 ~ 2029-10-05 |
| SHA256 | 2CAE62746C588889DC5241BA2FD16EC6D4DEF0C74AA2DEF402109CA5A5EEDDD6 |
⚠️ 重要说明:这是自签名证书
- ✅ 可验证文件在签名后未被篡改
- ❌ 不会让 Windows 显示"已验证的发布者",仍会显示"未知发布者"
- ❌ 不会消除 SmartScreen 或浏览器下载警告
要消除这些警告,需要购买 CA 签发的代码签名证书(OV 约 ¥2000/年,EV 约 ¥4000/年)。
自签名适用于内部/自用分发,以及完整性校验。
自行验证签名
`powershell
校验文件完整性
Get-FileHash kshell_windows_x64_v2.1.exe -Algorithm SHA256
应输出 2CAE62746C588889DC5241BA2FD16EC6D4DEF0C74AA2DEF402109CA5A5EEDDD6
查看签名
Get-AuthenticodeSignature kshell_windows_x64_v2.1.exe | Format-List Status, SignerCertificate, TimeStamperCertificate
`
Status 显示 UnknownError(证书链在不受信任的根终止)是自签名证书的预期结果。
详见仓库 signing/README.md。