尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

CLI-Anything:把重复命令封装成统一命令行入口的实践指南

发布时间:2026/9/28 17:24:45

资讯中心
01
ARTICLE

CLI-Anything:把重复命令封装成统一命令行入口的实践指南

CLI-Anything:把重复命令封装成统一命令行入口的实践指南
如果你和我一样每天要在终端里敲几十遍几乎相同的命令迟早会产生一个念头能不能把所有这些操作统一成一条命令我最近用一周多的业余时间折腾了一个叫 CLI-Anything 的小项目灵感很简单——Anything 都能成为 CLI。这个项目把重复的 Git 操作、Docker 清理、目录切换甚至对 Codex CLI 和 Claude CLI 的调用全部收编到了同一个入口里。它不是某个大厂的正式产品而是适合所有终端使用者的个人脚手架。无论你是被命令行劝退过的新手还是已经写了多年脚本的老手都可以从里面抄走一部分设计或者直接把它 clone 下来改造成自己的工具箱。今天这篇就把我的设计思路、完整实现、踩过的坑一次说清楚。1. 为什么会有 CLI-Anything从“记命令”到“造命令”1.1 一切皆命令的灵感来源CLI 的本质其实非常简单一个命令就是一个可复用的输入输出转换。你给它参数它产生结果。我之所以想到做 CLI-Anything是因为我发现自己在终端里的日常可以被拆成三件事查状态、改东西、跑流程。这三件事的命令参数通常又长又容易记错。打个比方这就像厨房里的一堆调料。做一次菜要临时想放几克盐、几勺生抽、什么时候下锅每次都要重新配比。如果你把常用的做法做成固定调料包做菜时就省掉大量重复决策。命令行也一样复杂操作封装成一条短命令以后只面对那个短命令而不用面对背后的二十个参数。命令行本身已经提供了这三件事的原子积木git负责版本状态、docker负责容器、curl负责网络请求、jq负责解析 JSON。但它们彼此之间没有“胶水”每次组合都要重新写一遍。CLI-Anything 就是这一层胶水。1.2 它到底解决什么问题往小了说CLI-Anything 解决四类问题重复操作每天都要执行git add -A git commit -m xxx git push为什么不直接敲ggpush xxx记忆成本ffmpeg转码、rsync同步这类命令参数极多真正用到时还要翻历史记录。跨工具调用查完日志还要转去另一个工具跑数据分析命令之间互不相通。团队复用你自己磨合出来的命令为什么不能一键分享给同事这些问题的共通点是把“人的经验”沉淀成“可执行文件”。CLI-Anything 提供一个统一的入口、统一的帮助信息、统一的错误返回码让沉淀下来的脚本不再是散落各处的.sh文件而是一个“工具箱”。对我个人来说它最大的价值是“卸载记忆负担”我不需要记住某个操作的具体参数只需要记得这个操作在工具箱里叫什么名字。2. 核心设计一个“什么都能长出来”的命令骨架2.1 目录结构与命令注册机制CLI-Anything 的骨架非常轻核心思路是“一个子命令对应一个可执行文件”。这种设计在 Go 的 cobra、Rust 的 clap 里很常见但我们不需要引入多复杂的框架一个目录加一个小脚本就能实现。项目结构大概是这样的cli-anything/ ├── bin/ │ └── cli-anything # 统一入口脚本 ├── commands/ │ ├── ai-commit.sh │ ├── docker-clean.sh │ ├── weekly-report.sh │ └── ... ├── lib/ │ └── helpers.sh # 公共函数 ├── config.env # 全局配置 └── README.md入口脚本只做一件事从commands/目录里找到与第一个参数同名的文件然后执行它。如果找不到就打印帮助信息。#!/usr/bin/env bash # bin/cli-anything set -euo pipefail COMMAND_NAME${1:-} shift 2/dev/null || true if [[ -z $COMMAND_NAME ]]; then echo Usage: cli-anything command [args...] echo echo Available commands: for f in commands/*.sh; do name$(basename $f .sh) desc$(head -1 $f | sed s/^# //) printf %-24s %s\n $name $desc done exit 0 fi SCRIPTcommands/${COMMAND_NAME}.sh if [[ ! -f $SCRIPT ]]; then echo error: unknown command ${COMMAND_NAME} 2 echo Run cli-anything to see available commands. 2 exit 1 fi # 让子命令可以访问公共函数和配置 source lib/helpers.sh source config.env exec bash $SCRIPT $这段脚本我用了set -euo pipefail。-e保证任何一步出错就停下来-u避免用到未定义变量pipefail防止管道中的错误被吞掉。这算是 shell 脚本的三件套很多人不写等到出问题才后悔。唯一要注意的是如果你确实需要某个命令“即使失败也要继续”可以在子命令里临时关闭它。2.2 参数解析、帮助信息与错误处理每个子命令我都强制要求两件事必须能打印帮助信息必须用非零退出码表示失败。这两条规矩让整个工具箱的体验非常一致。以docker-clean.sh为例#!/usr/bin/env bash # 清理无用的 Docker 容器、镜像和构建缓存 set -euo pipefail usage() { echo Usage: cli-anything docker-clean [--force] echo --force 跳过确认直接清理 } while [[ $# -gt 0 ]]; do case $1 in --help|-h) usage exit 0 ;; --force) FORCE1 shift ;; *) echo error: unknown option: $1 2 usage 2 exit 1 ;; esac done if [[ ${FORCE:-0} ! 1 ]]; then read -r -p 确认清理所有无用的数据 [y/N] confirm if [[ $confirm ! y $confirm ! Y ]]; then echo 已取消 exit 0 fi fi docker system prune -af --volumes这个脚本本身不复杂但有几个细节值得说。第一个是read -r-r避免反斜杠被转义。第二个是默认交互式确认只有加--force才跳过这是防止手滑的保命设计。第三个是错误信息全部写到标准错误2不然在管道里排查问题时会特别痛苦。2.3 把“任何东西”变成子命令的三种打法CLI-Anything 之所以叫 Anything是因为往commands/里丢一个可执行文件它就是一个新命令。我总结下来子命令常见的来源有三种。第一种是直接包装把一段你复制粘贴了无数次的命令变成脚本。比如“一键提交代码”#!/usr/bin/env bash # 一键 add、commit、push set -euo pipefail git add -A git commit -m ${1:-chore: update} git push第二种是组合多个已有 CLI。命令行工具的强处是每个都很专注弱处是组合起来繁琐。你可以用 CLI-Anything 把“用户态工具链检查”这种流程串起来#!/usr/bin/env bash # 检查开发环境是否就绪 set -euo pipefail for cmd in git node go docker; do if command -v $cmd /dev/null 21; then echo OK $cmd else echo MISS $cmd fi done第三种是调用 API这通常需要写一点 Python。比如一份脚本把内部接口的数据拉到本地生成表格。这三种打法交替使用基本能覆盖日常 90% 的重复工作。3. 接入 AI CLI把 Codex CLI 和 Claude CLI 收编进命令箱3.1 安装 Codex CLI从 npm 到二进制最近 AI 编程助手在终端里越来越火Codex CLI 就是 OpenAI 官方出的命令行工具。它可以直接在终端里跑对话、生成代码、执行任务。我把它作为 CLI-Anything 的一个重要子命令来源因为“调用 AI”本身也是一件重复的事。安装 Codex CLI 最常规的方式是 npmnpm install -g openai/codex装完先验证版本codex --version如果能看到版本号说明安装成功。之后可以直接交互式启动codex也可以非交互式给一个任务codex 查看当前目录的项目结构并用树状图列出来我在实际使用中会把一些固定任务交给它比如“帮我的 commit message 起个标题”“给这段代码写单元测试”。这些任务本身很简单但每次都要描述一遍也很费精力。所以我在 CLI-Anything 里加了一个ai子命令后面详细说。安装时有一个高频错误unable to locate the codex cli binary or required runtime components。我在第 5 节会专门讲排查思路这里先说结论八成是 PATH 没有把 Codex CLI 的安装目录包含进去或者 Node.js 版本太低。3.2 配置 Claude CLIMac 上如何切换模型 KeyClaude CLI 是另一款非常好用的 AI 终端工具它默认读取ANTHROPIC_API_KEY这个环境变量作为凭据。如果你有自己的 Claude API Key直接在 shell 里 export 就行export ANTHROPIC_API_KEYsk-ant-...很多朋友在 Mac 上使用 Claude CLI 时想的不是用官方的模型而是把手上的其他模型 Key 接进去。比如我有一次想把 Qwen Key 配到 Claude CLI 里因为同样一套交互界面可以切到底层模型不同。社区里常见的做法是显式指定兼容的接口地址和模型名export ANTHROPIC_API_KEYsk-你的-qwen-key export ANTHROPIC_BASE_URLhttps://你的兼容接口地址 export ANTHROPIC_MODELqwen-max配置完以后启动claude时它就会用你指定的 Key 和模型。这里有个细节需要提醒环境变量的名字要区分大小写anthropic_api_key是无效的。我见过不止一次因为环境变量名小写了结果 CLI 像没带钱就进超市直接报错。更推荐的做法是把它写进~/.zshrc但不要把密钥直接硬编码进脚本仓库。可以单独放到一个不在 Git 仓库里的配置文件然后用source加载。3.3 在 CLI-Anything 里统一调度 AI 命令有了 Codex CLI 和 Claude CLI 之后下一步就是把它们塞进 CLI-Anything。我建了一个ai子命令用来区分调用哪个 AI 工具。#!/usr/bin/env bash # 统一 AI 命令入口 set -euo pipefail TASK${1:-} if [[ -z $TASK ]]; then echo Usage: cli-anything ai commit|review|weekly-report|chat exit 1 fi case $TASK in commit) codex 根据 git diff 生成一条符合 conventional commits 规范的 commit message ;; review) claude 请对当前分支的改动做一次 code review指出风险和优化点 ;; weekly-report) claude 根据 git log 生成周报 ;; *) echo error: unknown ai task $TASK 2 exit 1 ;; esac这样做的价值在于团队内部不用每个人都去记住“这个任务找 Codex那个任务找 Claude”只需要记cli-anything ai 什么什么。工具是可以替换的但入口保持一致。4. 从零实现一个真实子命令一键生成周报4.1 先定义输入和输出空谈设计容易飘我拿一个真实子命令完整走一遍。目标是做一个weekly-report命令基于 Git 提交记录自动生成一周工作总结。先定义输入日期范围的起始日期和结束日期可选使用哪个 AI CLI默认 claude可选输出文件路径再定义输出一份 Markdown 格式的周报包含本周提交统计、主要改动模块、AI 生成的总结段落4.2 写脚本并接入 CLI-Anything第一步是拿到提交记录。git log本身就能筛选日期范围和提交信息git log --since$start --until$end --prettyformat:%h %s为了让 AI 生成更自然的总结我把提交信息拼成一段有序列表再交给 Claude CLI 做整理。脚本如下#!/usr/bin/env bash # 基于 git log 生成周报 set -euo pipefail START${1:-$(date -v-7d %Y-%m-%d 2/dev/null || date -d 7 days ago %Y-%m-%d)} END${2:-$(date %Y-%m-%d)} OUT${3:-weekly-report-${END}.md} LOG_CONTENT$(git log --since$START --until$END \ --prettyformat:- %s --no-merges) if [[ -z $LOG_CONTENT ]]; then echo warning: 没有找到提交记录生成空周报 2 LOG_CONTENT- 本周无提交 fi { echo # 周报 ${START} 到 ${END} echo echo ## 本周提交记录 echo echo $LOG_CONTENT echo echo ## AI 总结 echo } $OUT claude 以下是 ${START} 到 ${END} 的提交记录请用三句话总结本周工作重点并给出下周建议 $LOG_CONTENT $OUT echo 周报已生成$OUT这个脚本有几个值得注意的处理。一是日期默认值的兼容写法date -v-7d是 macOS 的 BSD date 语法date -d 7 days ago是 Linux 的 GNU date 语法。我在脚本里用||做了双保险这样同一个脚本在 Mac 和 Linux 上都能跑。二是--no-merges过滤掉合并提交避免周报里全是 merge 噪音。三是即使没有提交记录也要生成空周报而不是直接报错。4.3 参数计算的完整过程很多 AI 调用会按 token 计费所以在交给模型之前我会先估算一下文本量和费用避免一条命令烧掉不必要的额度。一个粗略的估算公式token 数 ≈ 字符数 / 4。英文大概 4 个字符一个 token中文会高一些粗略按 1 到 1.5 个字符一个 token 算更保守。我在脚本里加了一段提示CHARS$(echo -n $LOG_CONTENT | wc -m | tr -d ) TOKENS_EST$((CHARS / 3)) echo 输入约 ${TOKENS_EST} tokens费用取决于当前模型单价 2假设本周提交 500 个汉字那估算大概 500 到 1600 tokens取中间值 800。如果当前模型输入单价是每百万 tokens 20 元那这次调用的输入成本约 0.016 元几乎可以忽略。如果提交记录特别丰富达到 1 万字符那估算 3000 到 10000 tokens成本也不过几毛钱。真正贵的是把整个仓库的 diff 都塞进去那样动辄几十万 token所以在设计命令时能传摘要就不要传全文。4.4 运行效果与结果校验脚本放到commands/weekly-report.sh后运行cli-anything weekly-report 2025-01-06 2025-01-10大约十几秒后目录下出现weekly-report-2025-01-10.md。打开文件前面是整理过的提交列表后面是 AI 总结。我遇到过一个有意思的情况某次git log里的提交信息全是“fix bug”“update”AI 写出来的总结也特别敷衍。所以后来我给自己立了个规矩提交信息要写清楚模块和意图否则下游所有自动化质量都会被打折扣。结果校验也很简单三步文件是否生成、AI 总结是否与提交记录一致、日期范围是否准确。有时候--until不写当天日期会漏掉当天最后几个提交因为git log默认按 00:00 边界算。要包含当天建议--until$END 23:59:59这个小坑很隐蔽。5. 常见问题与排查技巧实录5.1 unable to locate the codex cli binary or required runtime components这应该是 Codex CLI 用户遇到最多的报错之一。完整的报错类似unable to locate the codex cli binary or required runtime components. check your installation。它翻译过来就是“找不到 codex 的可执行文件或者缺少运行环境组件”。我排查这个问题的顺序是固定的先跑which codex看系统能不能找到这个命令。如果没有任何输出说明安装目录没进 PATH。再跑npm root -g拿到全局 node_modules 路径检查该路径下有没有openai/codex。确认 Node.js 版本node -v。Codex CLI 通常对 Node 版本有要求太低会直接跑不起来。如果二进制是从压缩包解压出来的检查文件是否有执行权限ls -l $(which codex)。最后尝试重新安装一次重点看安装日志末尾有没有异常。多数情况在第 1 或第 2 步就解决问题。如果是 PATH 的问题在~/.zshrc或~/.bashrc里加上全局 bin 目录export PATH$(npm root -g)/.bin:$PATH这是 npm 基础操作但很多人就是因为没加这一行卡在“装好了却用不了”的状态。5.2 PATH 不对 / 找不到命令这几乎是所有 CLI 工具的通病。command not found有几种情况没安装安装了但目录不在 PATH 里权限没给执行权限你用的 shell 和安装时用的 shell 不是同一个我有一个快速定位技巧先type codex或which codex。如果输出了/usr/local/bin/codex但执行还是失败那可能是动态库或解释器的问题。如果是 npm 全局安装可以npm list -g --depth0看看包是否真的存在。很多人在 Mac 上遇到“在终端里能用在脚本里不能用”的问题原因是 cron 或自动化脚本的环境变量少了~/.zshrc。这时要么在脚本开头显式source ~/.zshrc要么把 PATH 硬编码进去。我的做法是统一在config.env里定义路径CLI-Anything 入口会加载它。5.3 Mac 上 Claude CLI 使用 Qwen Key 的配置细节用 Qwen Key 接 Claude CLI 时最大的坑就是“环境变量名不匹配”和“接口地址不匹配”。我建议按这个顺序核对检查项正确做法变量名ANTHROPIC_API_KEY全部大写、下划线分割接口地址ANTHROPIC_BASE_URL必须是服务方提供的兼容地址注意结尾不要多带路径模型名ANTHROPIC_MODEL要和服务方支持的模型 ID 完全一致Shell 加载修改~/.zshrc后执行source ~/.zshrc或重开终端还有一个体验性建议不要直接覆盖全局的ANTHROPIC_API_KEY。如果你还有别的 Claude Key可以给不同 Key 起不同的别名alias claude-qwenANTHROPIC_API_KEYsk-xxx ANTHROPIC_BASE_URLhttps://... ANTHROPIC_MODELqwen-max claude这样同一个 CLI 工具可以一键切换后端互不干扰。5.4 网络超时、API 限额和权限问题调用 AI CLI 时另外两类高频问题是网络和时间。网络问题表现为请求超时、连接被拒、长时间无响应。这种时候先检查本机网络是否能正常访问目标 API用curl -I简单试探一下再检查 API 服务方的状态页看是不是服务端在维护。不要每遇到超时就怀疑工具坏了很多时候是临时的网络抖动。API 限额问题则直接体现为 HTTP 429 或 403说明当前 Key 的配额用完了或者权限不够。排查思路是登录服务平台看用量、检查 key 是否还有有效期、确认请求头里的模型 ID 是否有权限。我建议在 CLI-Anything 的配置里不要把 key 写死而是从环境变量读取一旦 key 轮换只需改一处。这些看起来都像是基础设施问题但落在日常工作中就是每个命令都可能遇到的事。有了统一入口以后我可以在入口脚本里加超时、日志、退出码汇总把这样基础设施问题也收口到一个地方。6. 后续扩展与我的心法6.1 从“我的工具箱”到“团队工具箱”CLI-Anything 做到这个程度本质上已经是一个可复用的开发工具链。我之后还想做的扩展是把这些子命令推给团队使用统一帮助、统一配置、统一错误处理新人加入时只需要跑一条setup.sh。还有几个我想加的玩法给所有子命令加--json输出方便脚本之间继续处理。把耗时命令接入通知执行完弹一个本地通知。对接定时任务周五下午自动生成周报并发到邮箱。把ai子命令的大模型参数做成可配置让团队成员各自选模型。这些扩展并不难难的是保持“入口简单、子命令单一”的设计惯性。每多一个花哨功能都要问自己一句这个功能真的应该放在 CLI 里吗如果答案是“偶尔需要”那就不如不加。6.2 我在实际使用中的几点体会折腾 CLI-Anything 这周我最大的体会是先有重复再有封装。很多人一上来就想着“我要写一个万能框架”结果根本没想清楚解决什么问题最后只得到一个漂亮但没有用户的项目。我的建议是先把自己的高频操作记下来至少连续记三天再挑出现次数最多的那几条写成子命令。这样每条命令都是真实需求不是臆想。第二个体会是输出要比输入更友好。命令行脚本不一定非要追求全是字符可以适当加一点颜色提示、分隔线、进度信息。我通常会在脚本里输出“命令名称、耗时、结果路径”这三样信息让使用者在屏幕上一眼就能判断是否成功。第三个体会是别怕用 AI 帮忙写脚本。像这种小工具完全可以让 Codex CLI 先给你一版你来改边界条件。实测下来AI 写的脚本骨架一般比手写更快但路径处理、异常输出、兼容性这些坑还是要靠人把关。工具负责快人负责准配合起来才舒服。如果让我给一句话总结那就是CLI-Anything 不是一个终点而是一个可以一直生长的项目。今天你多写一条子命令明天你的工作就能少重复一次。把自己最常做的事情做成命令可能是对个人效率最值得的一笔投资。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。