Clasp 更新记:更顺手的新命令、更稳的插件系统
Clasp 更新记:更顺手的新命令、更稳的插件系统
本文基于开源项目 Clasp(MIT License)撰写。
距离上一篇介绍 Clasp 的文章已经过去一段时间,这个 .NET 10 命令行工具箱又往前走了好几步。这篇文章不重复基础架构,而是聊聊这段时间里真正落地的新能力和踩过的坑。
新增的命令
sshx:像本地一样操作远程机器
之前聊过 Clasp 的网络类命令,现在加了一个更贴近日常运维的场景——通过 SSH/SCP 执行远程命令或传输文件。
clasp sshx --profile work-server "ls -la /opt/app"
clasp sshx --profile work-server --mode scp --source ./local.txt --target /remote/path/
这里的 --profile 直接读取 ~/.ssh/config,不用每次手敲 -i 和用户名。内部实现会解析 Host 段,把 IdentityFile、User、HostName、Port 等字段映射到进程参数上,遇到通配符或 Include 也能兼容。对经常在多个服务器之间跳转的人,比单独维护一长串命令行参数省心很多。
fd:支持多线程与断点续传的下载命令
除了系统信息和文本处理,Clasp 还补齐了文件下载这个高频需求。新增的 fd 命令(全称 file-download)支持多线程分段下载、断点续传和常用请求头配置:
clasp fd -u https://example.com/large-file.zip -o ./large-file.zip --threads 8
clasp fd -u https://example.com/large-file.zip --stdin
clasp fd --file urls.txt
它的工作流程是先发一个 HEAD 请求探测文件大小和服务器是否支持 Range,如果支持且文件较大,就按线程数把文件切成多个区间并行下载;不支持时自动降级为单线程流式下载。
几个比较实用的细节:
- 断点续传:下载中断后再次执行同一命令,会从已下载位置继续,不会从头开始;
- 自动重试:单段下载失败会自动重试 3 次,指数退避;
- 灵活输入:除了
--url,还支持--stdin从管道读链接,或--file批量读取 URL 文件; - 请求头定制:
--user-agent、--referer、--cookie、--header都能配,方便处理需要登录或防盗链的资源; - 进度显示:终端里会实时刷新百分比、已下载大小和速度。
对经常在服务器之间传大文件,或者需要写简单脚本批量下载的人来说,这个命令比浏览器下载更可控,也比 curl / wget 多了一个内建的多线程和进度显示。
tree:目录结构的可视化输出
tree 命令几乎是每次查看项目结构时都会用到的。现在可以直接在终端里输出带缩进的目录树:
clasp tree --depth 2
clasp tree --dirs-only src
实现上用了递归遍历 + Unicode 制表符,输出和经典 tree 命令风格接近,但不需要额外安装。支持 --depth 限制递归深度,--dirs-only 只看目录,--hidden 控制是否显示隐藏文件。
log:文件内容的实时查看
日志排查是开发者的高频场景。Clasp 新增的 log 命令把常见的查看方式收拢在一起:
clasp log --follow ./app.log
clasp log --tail -n 200 ./app.log
clasp log --filter "ERROR" ./app.log
--follow 底层用 FileStream 配合 FileShare.ReadWrite 打开文件,不会和正在写入日志的进程产生文件锁冲突。--filter 则按行匹配正则表达式,方便在大量输出里快速定位关键信息。
json:更实用的格式化与转义
JSON 处理类命令之前已经具备格式化查询能力,现在补充了转义和反转义:
clasp json --escape '{"key": "a"b"}'
clasp json --unescape "{\"key\": \"value\"}"
--unescape 同时支持带引号的 JSON 字符串和裸字符串,内部通过双重序列化判断是否需要解析。这意味着从日志里复制出来的转义 JSON 也能直接还原,不用再手动处理反斜杠。
update 的稳定性改进
自更新是 CLI 工具很容易被忽视,但一旦出问题就很麻烦的模块。之前 Windows 版本在覆盖可执行文件时会出现文件锁,而且会弹出一个额外的 cmd 窗口。Linux 版本虽然能用,但脚本逻辑和 Windows 不一致,缺少权限处理。
现在的处理方式是:
- 解压到临时目录后,先生成平台对应的更新脚本;
- 脚本先循环检测旧进程是否退出;
- 确认退出后再用
xcopy(Windows)或cp(Linux)覆盖目标目录; - Linux 额外执行
chmod +x确保新程序可执行; - 最后启动新进程并清理自身脚本文件。
Windows 端通过 CreateNoWindow = true 隐藏更新窗口,Linux 端用 /bin/sh 直接执行,两端行为基本对齐。对于经常发布新版本的 CLI 工具来说,这种细节决定了用户会不会在更新时遇到"文件占用"或"权限不足"的困惑。
插件系统的加固
插件是 Clasp 区别于普通工具集合的核心。这段时间主要解决了三个实际问题:
依赖解析
之前插件 DLL 如果引用了第三方库,运行时会在 AssemblyResolve 里失败,导致插件加载被跳过。现在加载插件集会先挂载 AssemblyResolve 处理器,从插件所在目录和主程序依赖目录解析缺失程序集,加载失败时才静默跳过,不再因为缺少一个 NuGet 包而连带让整个插件不可用。
.cs 源码插件的缓存编译
除了编译好的 DLL,Clasp 也支持直接把 .cs 文件放进 plugins 目录。之前每次启动都会重新编译,哪怕代码没改动。现在会在插件同级目录生成 .meta 文件记录源文件最后写入时间,启动时先比对时间戳,只有源文件变化时才重新编译,编译结果缓存为 DLL。对只有几行代码的小插件来说,启动速度提升明显。
统一的加载路径
之前 DLL 和 .cs 插件的加载路径是分开的,容易在不同平台出现行为差异。现在统一先走编译/缓存流程,最终都通过 Assembly.LoadFrom 加载,再注入依赖解析器。内置命令和第三方插件在运行时走的是完全相同的注册管线。
写在最后
这一轮更新更像是在补齐一个 CLI 工具真正会高频使用到的能力:远程操作、日志查看、目录浏览、自更新稳定性,以及插件系统从"能用"到"好用"的细节打磨。
如果还没看过第一篇,建议先读最初的架构介绍;如果你已经在用 Clasp,欢迎把自定义插件或踩过的坑提 Issue。工具的价值从来不只是功能数量,而是能不能安静地融入日常 workflow。

浙公网安备 33010602011771号