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。

项目地址:https://github.com/wosledon/Clasp

posted @ 2026-09-04 17:24  胖纸不争  阅读(5)  评论(0)    收藏  举报