命令行工具的手感
我每天用命令行,也写过几个小工具。慢慢发现,评价一个 CLI 工具好不好用,标准不在功能多少,而在一种很难描述的东西——手感。
手感好的工具,第一次用就能猜对参数;手感差的工具,用了半年还要查帮助文档。
默认值暴露了作者的假设
看这几个写法:
tool convert input.md
tool convert input.md --output out.html --force --verbose
第一个版本假设:你只想把手头这个文件转一下,多余的别问。第二个版本假设:你随时可能搞砸,所以要你显式确认每一步。
两种假设都不算错,但它们的目标用户不同。危险操作(覆盖、删除、推送)需要显式确认;日常操作(转换、查询、预览)不该每次都被拦一下。
最糟的是把危险的默认值和啰嗦的确认放在一起:既不安全,又烦。
参数名要能被猜中
我给自己定的规矩是:如果一个参数名需要查文档才知道,那它就该被改掉。
- 表示”详细输出”的,用
-v/--verbose,不要用--log-level=debug - 表示”只预览不写入”的,用
--dry-run,不要用--no-execute - 表示”递归处理子目录”的,用
-r/--recursive
行业里已经有一批事实标准了。除非有极强理由,否则不要另起炉灶——使用者的肌肉记忆是免费的,你只需要不跟它作对。
输出要能接进管道
一个工具的输出,很可能不是给人看的,而是喂给下一个工具:
tool list --format=json | jq '.[] | select(.draft) | .title'
所以:面向人的输出走 stdout 时保持简洁整齐,面向机器的输出必须有一个显式开关(--json),而且两者不要混。日志、进度条、警告一律走 stderr,否则会污染管道。
这条我踩过坑:一个脚本把进度条打到了 stdout,结果 | jq 全部解析失败。当时以为是 jq 的问题,查了很久。
报错要告诉人怎么办
对比这两种报错:
Error: ENOENT
错误:找不到文件 content/notes/foo.md
提示:可用 `tool list` 查看所有文章的路径
第二种多花不了多少力气,但对使用者的价值差了一个数量级。报错信息里应该包含三样东西:发生了什么、涉及哪个对象、下一步能做什么。
小结
命令行工具没有图形界面可以藏拙。它好不好用,使用者三秒内就有判断。
我现在写完一个工具,会强迫自己隔一天再用一次,不看文档。手会自己找到答案,或者自己撞到墙上——撞到的每一次,都是一个该改的地方。