gogcli 输出契约完整指南:--json 与 --plain 如何让 stdout 永远可被脚本解析
【免费下载链接】gogcliGoogle Workspace in your terminal.项目地址: https://gitcode.com/GitHub_Trending/gogcl/gogcli
gogcli 是一个把 Google Workspace(Gmail、Drive、Calendar 等)装进终端的命令行工具。它最容易被忽视、却对自动化最重要的设计,是它的输出契约:只要加上--json或--plain两个全局参数,gogcli的标准输出(stdout)就永远只会是结构化数据或稳定的 TSV 文本,可以被任何脚本可靠解析。本文用最短的篇幅讲清楚这两个参数背后的完整机制。
为什么普通 CLI 输出很难喂给脚本 💥
把命令行工具接进自动化流水线时,最常见的翻车点不是功能,而是输出不可预期:
- 彩色高亮、进度条、提示语混在结果里,
jq直接解析失败; - 提示信息打到 stdout,导致重定向文件里混入垃圾文本;
- 换个终端宽度、换个 locale,列对齐就变了,
awk脚本当场崩溃。
gogcli的做法是:把"给人看的输出"和"给机器看的输出"严格分开,并且把规则固化在代码里,而不是靠使用约定。
两种机器输出模式:--json 与 --plain
gogcli提供两个全局输出开关,定义在 internal/cmd/root.go 的根参数中:
| 参数 | 别名 / 短写 | 输出形态 | 适用场景 |
|---|---|---|---|
--json | --machine/-j | 带缩进的 JSON,写入 stdout | 接jq、yq、任何语言解析器 |
--plain | --tsv/-p | 稳定 TSV 纯文本,无颜色、无对齐填充 | 接awk、cut、grep |
两者互斥:同时传入会被判定为用法错误,直接以退出码 2 失败,而不是被悄悄忽略。这条规则由 internal/outfmt/outfmt.go 中的FromFlags函数强制保证。
最简单的用法:
gog --json gmail search 'newer_than:7d' gog --plain calendar events --todaystdout 与 stderr 的硬隔离:契约的核心
"stdout 永远可解析"不是口号,gogcli的契约是:主数据写 stdout;提示、进度、警告、诊断信息一律写 stderr。
--json模式下的 JSON 由 internal/outfmt/outfmt.go 的WriteJSON统一编码,保证格式稳定;- 表格类命令在普通模式下用 tabwriter 对齐给人看,切到
--plain后 internal/outfmt/table.go 的WriteTable直接输出制表符分隔的裸 TSV,不再做任何视觉对齐。
也就是说,gog ... --json > out.json拿到的文件 100% 是合法 JSON;2>/dev/null可以安全地丢弃所有人类提示。这是"输出契约"里最关键的一条。
用 GOG_JSON 与 GOG_PLAIN 环境变量全局固定模式 🎛️
不想每条命令都写参数?设置环境变量即可(见 internal/outfmt/outfmt.go 的FromEnv):
export GOG_JSON=1 # 所有 gog 命令默认输出 JSON export GOG_PLAIN=1 # 默认输出 TSV优先级规则很明确:命令行显式参数 > 环境变量。在 JSON 与 TSV 同时生效时,GOG_JSON胜出,避免模式歧义。对 CI 脚本尤其友好:在环境文件里写一次,后续几百行命令都不用再想输出格式。
再瘦一层:--results-only 与 --select 字段投影
拿到 JSON 后还嫌大?两个 JSON 模式专属开关可以进一步瘦身:
--results-only:剥掉分页令牌等信封字段,只输出主结果数组;--select id,subject:只保留指定字段,支持a.b点路径;也可写作--fields、--pick、--project。
gog --json --results-only --select id,subject \ gmail search 'newer_than:7d'两者都会先解包再投影,规则细节记录在 docs/automation.md 的 "Machine output" 一节。
退出码契约:不解析 stderr 也能做分支判断
可解析的 stdout 只解决了一半问题,另一半是状态。gogcli定义了命名退出码(同样记录于 docs/automation.md),脚本直接按数字分支即可:
| 退出码 | 名称 | 含义 |
|---|---|---|
| 0 | ok | 成功 |
| 2 | usage | 参数/用法错误(如同时传 --json 和 --plain) |
| 4 | auth_required | 凭证缺失、过期或被吊销 |
| 5 | not_found | 资源不存在 |
| 7 | rate_limited | 触发 API 配额限制 |
| 8 | retryable | 网络超时等可重试故障 |
if out=$(gog --no-input --json drive get "$id"); then printf '%s\n' "$out" else case $? in 4) echo "重新登录" >&2 ;; 7|8) echo "稍后重试" >&2 ;; esac fi想程序化地读取完整退出码表?gog schema --json | jq '.automation.exit_codes'即可。
安全档案锁死输出模式:自动化再保险 🔒
当gogcli由 Agent 或他人调用时,还可以用**安全档案(safety profile)**把输出模式直接锁死。例如 safety-profiles/readonly.yaml 一类档案会把plain或json锁定为固定值:此时与之冲突的命令行参数会直接报错,而不会静默生效。机制实现见 internal/safetyprofile/ 与bake-safety-profile构建工具(cmd/bake-safety-profile/),可在编译期把策略"烘焙"进二进制。
速查清单 ✅
| 需求 | 用什么 |
|---|---|
| 让 jq 解析结果 | gog --json <command> |
| 让 awk/cut 解析结果 | gog --plain <command> |
| 整 shell 固定模式 | export GOG_JSON=1或GOG_PLAIN=1 |
| JSON 只留主结果 | --results-only |
| JSON 只留指定字段 | --select a,b.c |
| 无人值守 / CI | 追加--no-input |
| 只读兜底 | 追加--readonly |
一句话总结gogcli输出契约:数据只走 stdout,噪音只走 stderr,格式由参数决定,状态由退出码表达。掌握了这四条,你的脚本就再也不会被终端输出"绊倒"。
【免费下载链接】gogcliGoogle Workspace in your terminal.项目地址: https://gitcode.com/GitHub_Trending/gogcl/gogcli
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考