今天整理了一个新的开源小工具:NUT(Network Utility Toolkit)。它是一个本地优先的终端网络工具箱,目标不是做成很重的网络平台,而是把我日常会反复用到的几个网络相关操作收在一个命令里:下载文件、临时开 HTTP 文件服务器、检查目标站点、看 Wi-Fi 信息。
项目地址:Rhythmicc/nut。目前它还是一个 early MVP,命令参数和 JSON schema 后面都可能继续调整,但基本方向已经比较清楚:交互式时好用,非交互式时也好接脚本。
为什么想写这个
很多网络小需求其实都不大,但经常会打断上下文。比如临时下载几个文件,要么复制一串 curl / wget 命令,要么打开浏览器;想把本机某个目录临时分享出去,又要找一个 file server;想看一个 URL 最终跳到哪里、TLS 用的什么、证书什么时候过期,又会临时拼几条命令。
NUT 想解决的是这种“零散但高频”的场景。它不会替代专业工具,也不会试图把每个功能都做满,而是把这些常见动作放到一个统一入口里:直接运行 nut 进入终端工具箱;需要进脚本时,就用 nut get、nut inspect、nut wifi 这样的显式子命令。
技术栈:Go + Bubble Tea v2
NUT 目前是纯 Go 项目,交互界面基于 Bubble Tea v2,组件层用了 bubbles 的 list、textinput、progress、filepicker,再用 lipgloss 做一点终端样式。裸运行 nut 时会进入一个 toolbox home screen,可以从里面选择 Downloads、File server、Inspect target 和 Wi-Fi。
我比较在意的一点是:TUI 只是入口,不应该把工具锁死在全屏界面里。所以显式命令不会打开完整 toolbox。比如 nut get URL 在普通终端里只显示一个内联进度;加上 --plain 会输出稳定的 tab-separated 文本;加上 --json 则输出机器可读结果,方便接 jq 或日志系统。
nut
nut get https://example.com/archive.tar.zst
nut get --jobs 4 --connections 8 URL_A URL_B URL_C
nut serve --dir ~/Downloads --addr 127.0.0.1:8000
nut inspect https://example.com
nut wifi
nut --json inspect https://example.com
下载器:谨慎地做并发和分段
下载是 NUT 里目前实现得相对仔细的一块。它支持多个文件并发下载,也支持在服务器确认支持 Range 请求时,对单个大文件做并行分段下载。但这里有个很容易踩的坑:有些服务器会忽略 Range 请求,直接返回完整文件。如果下载器不检查清楚,就可能把完整响应当作多个分段重复写进去。
所以 NUT 的策略比较保守:先发 Range: bytes=0-0 做探测,只有服务器返回有效的 206 Partial Content 和匹配的 Content-Range 时,才启用 segmented download。否则就自动回退到单流下载。分段时会预分配 .nut.part 文件,并用 io.NewOffsetWriter 直接写对应偏移;全部成功后再 rename 成目标文件。
另外还有一些偏日常但重要的细节:已有文件不会被覆盖,会自动选择 file (2).ext 这样的名字;失败后会清理 partial 文件;每个 task 都有状态、总进度、速度和错误快照,这样 TUI、plain 输出和 JSON 输出可以共享同一套状态来源。
本地文件服务器
nut serve 做的是一个很简单的本地 HTTP file server。CLI 默认监听 127.0.0.1:8000,TUI 里可以用 file picker 选目录,再单独设置 host 和 port。默认只绑定 localhost 是有意的,因为“临时分享文件”这种功能一旦默认暴露到局域网,风险会比便利大。
这个功能没有复杂包装,底层就是 Go 的 http.FileServer,外面加上路径检查、生命周期管理和优雅关闭。它的定位也很明确:临时起一个服务给本机或受控网络用,而不是长期部署的文件托管。
Inspect:把几条排障命令收成一个结果
nut inspect 会对目标做 DNS 解析,并发起一次 HTTP HEAD 请求,输出最终 URL、响应状态、延迟、Server、Content-Type,以及 TLS 版本、cipher 和证书过期时间等信息。目标如果没有 scheme,会默认按 HTTPS 处理。
这个功能本质上是把我平时排查“这个域名到底解析到哪里”“是不是跳转了”“TLS 正不正常”时会看的几类信息合在一起。它不追求像专业网络诊断工具那样细,但足够快速给出第一眼判断。
Wi-Fi:先做只读信息
nut wifi 目前只支持 macOS,通过 system_profiler SPAirPortDataType -json 读取当前 Wi-Fi 接口、已连接网络和附近网络。它不会连接网络,也不会处理密码。这个限制是刻意的:第一版先把只读信息做好,避免过早碰系统配置和凭据管理。
一点取舍
NUT 现在的核心取舍是“本地、轻量、可脚本化”。有终端时,它应该像一个顺手的小工作台;没有 TUI、跑在 CI 或脚本里时,它应该安静地输出 plain text 或 JSON。这个边界对我来说很重要,因为很多 CLI 工具一旦加了好看的交互界面,就容易让非交互场景变得难用。
接下来如果继续做,我可能会优先补更稳定的 release、更多测试样例和更细的 JSON 输出约定。至于视频下载、媒体转换这些功能,暂时不打算放进 NUT。工具箱可以长大,但最好别长成一个什么都想管的东西。
评论