跳至内容

软件技术分享

关于电子游戏的方方面面

  • 游戏产业
    • 行业杂谈
    • 开发者采访
  • 游戏设计
    • 专题学习
    • 设计制作
  • 游戏热点
    • 游戏评测
    • 游戏攻略
    • 流行游戏
  • 工具指南
  • AI
    • AI新闻
    • 使用心得
  • 小游戏
  • 游戏7×24小时
  • 关于妙游社

Codex:给脚本加 `–help` 与退出码,方便 CI 接住

作者 2026年11月6日 02:42

写 CLI 时强制 --help 与干净退出码(成功 0/失败非 0);stdout/stderr 分开,上层用 $? 接住。

要点

  • 交付清单四件套:--help/-h 列出用法与退出码约定;成功路径 sys.exit(0)/exit 0;可预期失败(缺参、校验失败、业务否决)用非 0;人读日志走 stderr,机器要解析的主结果走 stdout。证据强度:高(CLI 惯例;可跟做)。
  • 禁止“失败了还 exit 0”:上层 CI/Makefile/父脚本只看进程码时,会把翻车当成绿。证据强度:高(运维常识)。
  • 动机旁及:codex exec 在 CI 里进程 exit 0 往往只表示“这一回合跑完了”,不等于内部命令或项目自测已通过;社区 issue/笔记多次复现“内层失败、外层仍 0”(GitHub #15536、Kogen 笔记)。证据强度:中高(公开 issue/探针;官方 non-interactive 页未给完整 exit 表;是否已在你用的 CLI 版本修好,以发行说明与本机复现为准)。
  • 官方 non-interactive:codex exec 进度走 stderr、最终 agent 消息走 stdout,方便管道;自动化仍要你自己的测试/schema/门禁收口(Non-interactive mode)。证据强度:高(官方)。
  • 入门做法:把四件套写进给 Codex 的任务提示+验收命令;用最小 Python argparse 或 bash 示例当对照。证据强度:高(可跟做)。

正文

场景

你让 Codex 写了个 tools/sync_fixtures.py。本地手跑“像是好了”。丢进 CI:python tools/sync_fixtures.py 失败时仍返回 0,下一步 deploy 照样启动;或者帮助信息只在报错堆栈里,新人不知道有哪些子命令。

Agent 优化的是“把活干完”。CI 要的是“进程码说话”。这两件事不会自动对齐,得你在提示里写死。

可跟做步骤/可抄工作流

证据强度:四件套=惯例高;codex exec 出口语义=官方管道约定高+社区失败传播问题中高;示例代码=演示,非某仓库复刻。

1. 任务提示里写死交付物

可抄进 Codex/Agent 首条消息:

写/改 scripts/xxx 这个 CLI,必须同时交付:
1) --help 与 -h 能打印用法;写出子命令(如有)和退出码约定
2) 成功:进程退出码 0
3) 可预期失败(缺参、文件不存在、校验失败):非 0;不要 catch 后静默成功
4) 给人看的进度/警告走 stderr;给管道解析的主结果走 stdout
5) 自测:跑 --help;再各跑一条成功与一条失败路径,贴 exit code
先给计划,等我说 go 再改文件。

2. 最小 Python 示例(标明示例)

下面是演示示例,勿当某仓库原样拷贝。重点看 argparse 怎么带退出码,以及 stderr 怎么用。

#!/usr/bin/env python3
"""示例:带 --help 与退出码约定的最小 CLI。"""
from __future__ import annotations

import argparse
import sys
from pathlib import Path


def build_parser() -> argparse.ArgumentParser:
    p = argparse.ArgumentParser(
        prog="sync_fixtures",
        description="Sync local fixtures. Exit 0 on success; 2 on usage/validation errors.",
    )
    p.add_argument("source", type=Path, help="Source fixtures directory")
    p.add_argument("dest", type=Path, help="Destination directory")
    p.add_argument("--dry-run", action="store_true", help="Print plan only")
    return p


def main(argv: list[str] | None = None) -> int:
    args = build_parser().parse_args(argv)
    if not args.source.is_dir():
        print(f"error: source not a directory: {args.source}", file=sys.stderr)
        return 2
    if args.dry_run:
        print(f"would sync {args.source} -> {args.dest}")  # stdout:可被管道接住
        return 0
    args.dest.mkdir(parents=True, exist_ok=True)
    # ... 真实拷贝逻辑 ...
    print(f"synced {args.source} -> {args.dest}")
    return 0


if __name__ == "__main__":
    sys.exit(main())

argparse 自带 -h/--help。约定写进 description,失败时 return 2 再 sys.exit。

3. 最小 bash 示例(标明示例)

#!/usr/bin/env bash
# 示例:--help + 退出码
set -euo pipefail

usage() {
  cat <<'USAGE'
usage: sync_fixtures.sh SRC DEST
  --help   show this help
Exit codes: 0 success; 2 usage/validation error
USAGE
}

if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then
  usage
  exit 0
fi
if [[ $# -lt 2 ]]; then
  usage >&2
  exit 2
fi
echo "sync $1 -> $2"
exit 0

4. 验收清单(交给 Agent 跑完贴结果)

python scripts/sync_fixtures.py --help
python scripts/sync_fixtures.py /no/such /tmp/out; echo "exit=$?"
# 期望:缺源目录时 exit 非 0,错误在 stderr

python scripts/sync_fixtures.py ./fixtures /tmp/out --dry-run; echo "exit=$?"
# 期望:exit=0,计划在 stdout

CI 里同理:

- run: python scripts/sync_fixtures.py ./fixtures ./out
# 下一步 job 依赖本步成功:此处必须靠非 0 挡住坏数据

5. 为何要跟 codex exec 的出口语义错开理解(一句动机)

官方文档写 codex exec 把进度打到 stderr、最终消息打到 stdout,方便管道(Non-interactive mode)。第三方整理也提到:完整 exit 码表官方未集中公布,脚本里宜把非 0 当失败,并用 --json/项目自测收口(Arantic 编译)。更扎手的是:有人复现“内层 command_execution 已失败,外层 codex exec 仍 exit 0”(#15536;Kogen)。所以:项目脚本自己的退出码要干净——别把“Agent 说做完了”当成 CI 绿灯。

是否已在你用的 CLI 版本修好,以发行说明与本机复现为准。

真实用户诀窍/反例

  • 诀窍:退出码写进 --help 正文。 后人(和下一轮 Agent)都看得到约定。
  • 诀窍:用法错误用 2,业务失败用 1(或项目统一表)。 先固定一张小表,别每脚本一套。
  • 诀窍:验收命令写进同一轮任务。 “贴 exit code”比“顺便测一下”更常真的跑。
  • 诀窍:CI 看脚本码,再看测试码。 两层都绿再发布。
  • 反例:except Exception: print(e) 然后正常结束。 日志有错、进程仍 0。
  • 反例:把错误信息只打在 stdout 且 exit 0。 管道下游当正常数据吃进去。
  • 反例:只教 Agent“写功能”,不提 --help。 两周后没人记得参数名。
  • 反例:以为 codex exec 一绿就等于仓库门禁过了。 外层 0 与项目自测是两件事。

适用边界

  • 本稿是入门实操:让 Codex/Agent 交的 CLI 能被 CI/父脚本用 $? 接住。
  • 不覆盖:给 codex exec 本进程设计完整 exit 码表、GitHub Action 密钥代理细节、每家公司的错误码规范长文。
  • #15536 是否关闭、现行 CLI 是否已传播内层失败,以发行说明与本机复现为准;动机句保留“仍须项目自测”。
  • 示例代码可改语言;要点仍是 help+退出码+流分工。

相关阅读

  • 虚幻引擎 6 一开放早期访问就去掉蓝图,Epic 说 Verse 更适合 AI 读
  • Grok vs Claude:同一道“竞品定价变更核查”谁更稳
  • Codex:失败回合怎么 rewind/缩小范围再开
  • Claude:把风格指南塞进 Project 指令的可维护写法
  • Claude Code 改了拒复刻规则:可以说出游戏名讲机制,但不能照抄
  • Grok:语音模式适合什么任务、不适合什么

浏览更多「AI」文章 ›

  • 要点
  • 正文
  • 场景
  • 可跟做步骤/可抄工作流
  • 真实用户诀窍/反例
  • 适用边界

文章导航

上一篇Grok vs Claude:同一道“竞品定价变更核查”谁更稳
下一篇虚幻引擎 6 一开放早期访问就去掉蓝图,Epic 说 Verse 更适合 AI 读

相关文章

虚幻引擎 6 一开放早期访问就去掉蓝图,Epic 说 Verse 更适合 AI 读 虚幻引擎 6 一开放早期访问就去掉蓝图,Epic 说 Verse 更适合 AI 读 Grok vs Claude:同一道“竞品定价变更核查”谁更稳 Grok vs Claude:同一道“竞品定价变更核查”谁更稳 Codex:失败回合怎么 rewind/缩小范围再开 Codex:失败回合怎么 rewind/缩小范围再开

评测设计产业杂谈

软件技术分享

关于电子游戏的方方面面

栏目

  • 游戏产业
  • 游戏设计
  • 游戏热点
  • 工具指南
  • AI
  • 小游戏
  • 游戏7x24小时
  • 关于妙游社

本站

  • 首页
  • 隐私政策
  • 联系我们
  • 关于妙游社
  • 工具指南专题
  • 文章 RSS

关注公众号

沙漏社公众号二维码

© 2026 软件技术分享

沪ICP备19032461号-1

目录

×
  • 要点
  • 正文
    • 场景
    • 可跟做步骤/可抄工作流
      • 1. 任务提示里写死交付物
      • 2. 最小 Python 示例(标明示例)
      • 3. 最小 bash 示例(标明示例)
      • 4. 验收清单(交给 Agent 跑完贴结果)
      • 5. 为何要跟 codex exec 的出口语义错开理解(一句动机)
    • 真实用户诀窍/反例
    • 适用边界
→ 目录