Skip to content

Modo não interativo codex exec: coloque-o para rodar em scripts e no CI

📚 Navegação da Série: O artigo anterior [27 Automação e CI/CD] apresentou o panorama geral de "colocar o Codex para trabalhar automaticamente no pipeline" — que tipo de trabalho deve ser automatizado e como configurá-lo no CI. Este artigo foca no comando mais central: codex exec, ou seja, o "modo não interativo" que roda sem abrir uma interface gráfica, processa um comando direto e encerra imediatamente. O próximo artigo [29 Integração com Slack / Linear e SDK] mostrará como conectá-lo a sistemas de IM e gerenciadores de chamados.

Pessoal, hoje vamos conversar sobre um comando que você inevitavelmente precisará usar cedo ou tarde: codex exec.

Mencionei brevemente no Artigo 08 "Interface de Linha de Comando CLI", dizendo que ele é como "pedir delivery": você faz o pedido (um prompt), a cozinha fecha para preparar e o resultado é entregue diretamente no terminal, sem exigir sua presença durante o processo. Mas aquele artigo foi apenas para você "saber que ele existia". Este artigo abre a porta dos fundos da cozinha para mostrar como o pedido é preparado, embalado e inserido nos pipelines de automação.

Por que dedicar um artigo inteiro a isso? Porque o modo interativo (quando você digita codex e entra na tela cheia) tem um ponto fraco crítico: ele assume que há uma pessoa real sentada em frente à tela — acompanhando a conversa, pressionando Enter para aprovar e revisando o diff. Mas se você quiser "revisar automaticamente os commits de ontem todas as manhãs", "fazer com que o Codex crie um PR de correção se o CI falhar" ou "direcionar os erros de compilação para ele gerar um resumo da causa raiz" — não há nenhuma pessoa real nesses cenários. Nesses momentos, a interface interativa não apenas é inútil, mas também trava o processo esperando indefinidamente pela sua aprovação. O codex exec foi criado especificamente para cenários "sem intervenção humana".

Em poucas palavras, aprender a usar o codex exec é o divisor de águas entre apenas "usar a ferramenta Codex" e "transformar o Codex em uma peça de engrenagem do seu próprio fluxo de trabalho".

Ao ler este artigo, você obterá:

  • Uma explicação direta sobre a diferença essencial entre o codex exec e o modo interativo, e quais cenários "sem supervisão humana" ele resolve.
  • Compreensão sobre o seu design mais crítico: o progresso vai para o stderr e o resultado final para o stdout — essa separação torna a integração de pipelines extremamente simples.
  • Como combinar --json (eventos de processo legíveis por máquina) e -o / --output-last-message (extrair o resultado final para um arquivo) para atender a ambas as necessidades no CI.
  • O fato de a sandbox do modo não interativo ser somente leitura por padrão (sendo necessário liberá-la explicitamente para modificar arquivos) — acompanhado de uma tabela de comparação dos níveis de segurança.
  • Quando usar as duas abordagens de pipes do stdin (prompt + pipe como contexto vs codex exec - usando o stdin como o próprio prompt).
  • Um passo a passo prático mínimo para você replicar, realizando o ciclo completo: "rodar uma vez → obter o resultado → criar um script para rodar em lote".

⚠️ Qualquer subcomando, opção ou comportamento padrão mencionado abaixo segue a documentação oficial do Codex; nomes de modelos e versões que mudam com o tempo dependem do que estiver instalado localmente, não sendo fixados neste artigo.


01 Compreenda primeiro: para quem o modo não interativo foi criado

Começando pelo veredito: o codex exec resolve cenários "sem supervisão humana" — situações em scripts, tarefas agendadas (cron jobs) e pipelines de CI onde ninguém pode aprovar alterações em tempo real ou monitorar caixas de diálogo. O trabalho deve rodar até o fim sozinho e o resultado precisa ser consumido pelo próximo programa.

Pensando nos artigos anteriores, estivemos quase sempre usando o "modo interativo" — digitando codex para entrar na interface em tela cheia, fornecendo uma instrução, acompanhando o progresso passo a passo e clicando em "concordar" quando ele precisa alterar algo. Esse modo é excelente para 90% das tarefas, desde que você esteja presente.

Mas existem três tipos de tarefas em que você não quer ou simplesmente não pode estar presente.

O primeiro tipo: tarefas repetitivas e tediosas. Por exemplo, "gerar notas de lançamento (release notes) para os 10 commits de ontem todos os dias". Não é um trabalho difícil, apenas chato — você não quer abrir manualmente o Codex toda manhã, copiar os commits, esperar ele redigir o texto e colá-lo em outro lugar.

O segundo tipo: ambientes sem interface gráfica. Em pipelines de CI, servidores na nuvem ou contêineres Docker, não há um terminal para você "ficar vigiando", impossibilitando a execução do TUI (Terminal User Interface) interativo em tela cheia.

O terceiro tipo: quando você precisa enviar a saída do Codex para outro programa. Por exemplo, pedir para ele formatar um log em uma tabela Markdown e gravar o resultado diretamente em um arquivo, ou passar a saída via pipe para o gh pr comment publicar um comentário no PR. Isso exige que a saída do Codex seja tão limpa quanto a de uma ferramenta de CLI padrão, em vez de uma tela cheia de elementos visuais coloridos e interativos.

Analogia: Máquina de vendas automática (vending machine) vs Balcão com atendente. O modo interativo é como o balcão com atendente — você pede o que quer, ele prepara na hora, pode perguntar no meio do caminho se você quer "açúcar ou adoçante" e entrega em mãos. O codex exec é como uma máquina de vendas automática — você aperta o botão (um comando), a máquina funciona internamente e o produto cai na gaveta de retirada (resultado enviado para o stdout). Não há atendente, ninguém fará perguntas e sua presença é totalmente desnecessária. A vantagem da máquina é justamente ser "autônoma": funciona às três da manhã, em um pipeline ou em lote para cem servidores.

Na prática, o codex exec é mais utilizado nos seguintes cenários:

  • "CI falhou: localizar automaticamente o caso de teste que falhou e propor um patch de correção" — sem supervisão humana no pipeline, roda de forma totalmente autônoma.
  • "Gerar release notes para os últimos 10 commits e salvar em um arquivo" — tarefa repetitiva, automatizada em um script executável com um único clique.
  • "Passar logs de erro via pipe para ele gerar a causa raiz + próximos passos de diagnóstico" — executado em uma linha de comando, muito mais rápido do que copiar e colar na interface interativa.

💡 Resumo em uma frase: O codex exec foi criado para cenários "sem supervisão humana" (como uma máquina automática autônoma) — ideal para tarefas repetitivas, ambientes sem interface gráfica e situações em que a saída precisa ser consumida por outros programas, evitando a espera passiva do modo interativo.


02 Primeiros passos: o uso mais simples

Não se assuste com termos como "não interativo" ou "CI"; o uso mais básico do codex exec é extremamente simples — basta digitar codex exec seguido do seu prompt entre aspas, dar Enter e ele começa a trabalhar.

bash
codex exec "总结这个仓库的结构,列出最该警惕的 5 个地方"

Ele lê o diretório de trabalho atual, cria um plano, exibe o progresso na tela e, por fim, imprime o resumo e encerra — sem entrar no TUI ou travar a tela esperando que você pressione alguma tecla. Este é o significado mais direto de "não interativo": ele executa e encerra, sem conversas adicionais.

Analogia: Enviar um e-mail com uma tarefa e aguardar a resposta. O modo interativo é como uma ligação telefônica — conversa de duas vias, onde você pode interromper a qualquer momento. O codex exec é como enviar um e-mail — você detalha a tarefa que precisa ser feita no corpo da mensagem (o prompt), envia e a outra pessoa resolve o problema de portas fechadas, retornando com uma resposta (o resultado final). Você não pode mudar os requisitos no meio da execução, portanto, o prompt deve ser claro e completo desde o início.

Algumas variantes que você pode testar imediatamente:

bash
# 短别名 codex e,跟 codex exec 完全等价
codex e "解释这个项目是干什么的"
bash
# 换个模型跑这一次(模型名以你本地实际为准,别照抄)
codex exec -m gpt-5.5 "审查当前改动,列出潜在 bug"
bash
# 不想把这次会话记录落盘,加 --ephemeral
codex exec --ephemeral "快速过一遍这个仓库,给点下一步建议"

Um ponto extremamente importante que merece atenção: a maior diferença em relação ao modo interativo. No modo interativo, se o Codex precisar fazer alterações no meio do caminho, ele pausa e pergunta se você "aprova ou não". O codex exec foi projetado para cenários "sem supervisão humana", portanto ele não exibirá solicitações de aprovação esperando pelo seu aval. Isso traz o benefício da automação autônoma, mas também envolve riscos — o limite do que ele pode alterar depende inteiramente do nível da sandbox definido no momento da inicialização. Abordaremos isso na Seção 04; por enquanto, lembre-se de que "ele não fará perguntas no meio do caminho".

⚠️ Requisito obrigatório de um repositório Git: O Codex exige obrigatoriamente que o comando seja executado dentro de um repositório Git (pode ser contornado com --skip-git-repo-check) para evitar danos irreversíveis em locais sem controle de versão. Se você executar o codex exec em um diretório que não seja Git, ele interromperá a execução imediatamente. Se precisar rodar em um diretório temporário, adicione --skip-git-repo-check para ignorar essa validação — mas a recomendação oficial é fazer isso "apenas quando tiver certeza de que o ambiente é seguro".

💡 Resumo em uma frase: O comando codex exec "um prompt" é a execução não interativa mais básica (com o atalho codex e), funcionando como o envio de um e-mail com uma tarefa aguardando resposta — o prompt deve ser detalhado de uma só vez, ele executa e encerra, sem interrupções para pedir aprovação; há também um pré-requisito rígido: exige execução em um repositório Git, exigindo a flag --skip-git-repo-check para contornar em diretórios comuns.


03 O design mais crítico: progresso via stderr, resultado via stdout

Esta seção é a mais crucial deste artigo, representando o segredo para integrar o codex exec de forma elegante em seus pipelines.

Para começar: o Codex imprime muita informação durante a execução — seus pensamentos, comandos executados, arquivos alterados... no entanto, o que você realmente precisa costuma ser apenas o resumo final. Se todas essas informações fossem misturadas na saída padrão, ao tentar "gravar o resultado em um arquivo", ele ficaria poluído com ruídos do processo, inviabilizando o uso.

A solução do Codex é extremamente limpa: separar os dois tipos de saída em dois canais ("tubulações") diferentes.

O ruído do processo é enviado para o stderr (saída de erro padrão), enquanto o resultado final é direcionado para o stdout (saída padrão). Ambos são fluxos de saída independentes do terminal Unix. Embora você os veja misturados na tela durante a execução normal, os pipes | e redirecionamentos > capturam apenas o stdout por padrão. Portanto, essa divisão torna a extração de resultados incrivelmente simples.

Analogia: Em um canteiro de obras, o "ruído da construção" e a "casa finalizada" saem por portões diferentes. O processo de construção é barulhento — estacas sendo batidas, concreto misturado, marteladas (tudo isso vai para o stderr, você ouve, mas não é o produto final); a entrega final é uma casa limpa (que vai para o stdout, o que você realmente deseja). O barulho da obra sai pelo portão lateral do canteiro, enquanto o produto acabado é entregue pela entrada principal — com os dois portões separados, você não recebe uma avalanche de ruídos ao coletar o seu "produto final".

Veja como isso simplifica o processo. O comando abaixo exibe o resultado final tanto na tela quanto o salva em um arquivo (utilizando o tee), enquanto o progresso da execução continua rolando na tela, mas sem entrar no arquivo:

bash
codex exec "给最近 10 个提交生成发布说明" | tee release-notes.md

Resultado esperado: Você verá o processo de trabalho do Codex na tela (via stderr) e, ao terminar, a nota de lançamento final será impressa; ao mesmo tempo, o arquivo release-notes.md conterá apenas as notas de lançamento limpas, sem qualquer ruído do processo.

Compreendido esse redirecionamento, as seguintes operações comuns tornam-se naturais:

O que você deseja fazerComo escreverComo funciona
Salvar apenas o resultado em um arquivocodex exec "..." > out.md> captura apenas o stdout (resultado), enquanto o stderr continua aparecendo na tela
Salvar o resultado e visualizar simultaneamentecodex exec "..." | tee out.mdtee salva uma cópia do stdout no disco e imprime outra na tela
Passar o resultado via pipe para o próximo programacodex exec "..." | pbcopyO programa seguinte recebe apenas a saída limpa do stdout
Salvar também o ruído do processocodex exec "..." > out.md 2> log.txt2> salva o stderr separadamente em outro arquivo

Eu mesmo cometi um pequeno erro ao escrever meus primeiros scripts: na época, eu queria "salvar a saída do Codex em um arquivo" e acabei usando 2>&1 para mesclar o stderr ao stdout, fazendo com que o arquivo ficasse cheio de logs de progresso como "pensando" ou "lendo arquivo". O resumo final ficou perdido no meio daquela bagunça, quebrando completamente a análise do programa seguinte. Só depois percebi — o sistema foi projetado especificamente para separar o resultado dos ruídos, e eu acabei misturando tudo novamente. Ao remover o 2>&1, o arquivo ficou perfeitamente limpo.

💡 Resumo em uma frase: O codex exec direciona os ruídos do processo para o stderr e o resultado final para o stdout (como separar a saída de entulho da entrega das chaves da obra), garantindo que >, tee e pipes capturem apenas o resultado limpo; evite mesclar os canais usando 2>&1, caso contrário seu arquivo ficará cheio de logs de progresso.


04 Permissões e segurança: o modo não interativo é "somente leitura" por padrão

Começando pela conclusão, que também é o erro mais comum por falta de atenção: o codex exec roda por padrão em uma sandbox somente leitura — ele pode ler, analisar e fornecer recomendações, mas não modificará seus arquivos nem executará comandos com efeitos colaterais por padrão. Para permitir que ele faça modificações reais, você deve liberar o acesso explicitamente.

Por que esse padrão tão conservador? Porque ele foi projetado para operações "sem supervisão" — não há ninguém para interrompê-lo se algo der errado. Se a permissão de escrita estivesse liberada por padrão sem supervisão humana, qualquer falha de interpretação poderia causar alterações indesejadas em todo o seu repositório. Por isso, a filosofia de design oficial é: na automação, conceda apenas a permissão mínima necessária para o fluxo de trabalho.

Analogia: Entregar a chave da sua casa para um técnico de manutenção. Se você não está em casa e precisa de um reparo, você não entregaria todas as chaves da casa junto com a senha do cofre. Por padrão, você daria acesso apenas à sala para ele inspecionar o local (somente leitura); se ele precisar consertar um encanamento, você entrega apenas a chave da cozinha ou do banheiro (workspace-write, limitando a ação ao ambiente de trabalho); a menos que seja um ambiente totalmente isolado, você nunca daria uma chave mestra para ele "mexer em tudo, incluindo a casa dos vizinhos" (danger-full-access). Quanto mais restritas forem as permissões, mais segura será a execução autônoma.

A liberação de permissões é controlada pelo parâmetro --sandbox (ou o atalho -s), conforme detalhado na tabela comparativa abaixo:

Nível da SandboxO que pode fazerQuando usar
read-only (padrão do exec)Somente leitura e análise; não altera arquivos nem executa comandos com efeitos colateraisRevisão de código, geração de resumos, relatórios de análise — apenas saídas de texto
workspace-writeLeitura e escrita dentro do diretório do espaço de trabalho; realiza modificações diretasQuando for necessário alterar código, corrigir bugs ou gravar arquivos, mas limitando-se ao escopo do projeto
danger-full-accessQuase sem restrições; pode acessar e modificar toda a máquinaUso exclusivo em ambientes isolados (runners de CI independentes, contêineres)

Exemplos de comandos:

bash
# 默认只读:审查改动、只出报告,碰不到你的文件
codex exec "审查当前改动,列出潜在 bug"
bash
# 放开工作区写权限:让它真去修,但只在项目目录内动手
codex exec --sandbox workspace-write "修好失败的测试用例"
bash
# 仅限隔离环境:几乎不设限
codex exec --sandbox danger-full-access "<在隔离 runner 里的任务>"

Alguns pontos críticos de atenção que você precisa conhecer:

Atenção 1: Evite usar --full-auto. Você pode encontrar codex exec --full-auto em scripts legados, mas essa flag agora é um parâmetro de compatibilidade obsoleto (deprecated) e o Codex emitirá um alerta caso você a utilize. A recomendação oficial é substituí-la diretamente por --sandbox workspace-write em novos scripts, o que deixa a intenção muito mais clara.

Atenção 2: Use danger-full-access apenas em ambientes isolados. Esse nível concede controle praticamente irrestrito. A documentação oficial enfatiza que ele deve ser usado "apenas em ambientes controlados (como runners de CI dedicados ou contêineres)". Usar esse nível em sua máquina de desenvolvimento diária com projetos importantes é equivalente a entregar uma chave mestra da sua casa.

Atenção 3: Para garantir uma "inicialização limpa" em automações, existem duas flags de exclusão. A flag --ignore-user-config faz com que a execução ignore o arquivo $CODEX_HOME/config.toml (evitando interferências de configurações pessoais locais ou de colegas de equipe); a --ignore-rules faz com que ele ignore os arquivos .rules de política de execução (execpolicy) tanto do usuário quanto do projeto. Ambas as úteis para garantir que o comportamento seja idêntico em qualquer máquina.

No ano passado, eu mesmo enfrentei problemas ao presumir as permissões em uma tarefa de CI: achei que o codex exec usaria as mesmas configurações que eu uso no modo interativo (onde geralmente mantenho a permissão de escrita ativa), mas ele rodou no CI sem alterar absolutamente nada — fiquei totalmente confuso. Só ao consultar a documentação entendi que o modo não interativo é estritamente somente leitura por padrão, sendo um ambiente totalmente diferente do modo interativo. Ele só começou a modificar os arquivos depois que adicionei --sandbox workspace-write. Quase todo iniciante acaba caindo nessa armadilha do valor padrão.

💡 Resumo em uma frase: O codex exec roda em uma sandbox somente leitura por padrão (similar a permitir que o técnico acesse apenas a sala de estar). Para alterar arquivos, você deve definir explicitamente --sandbox workspace-write. O nível danger-full-access deve ser usado apenas em ambientes isolados; o antigo --full-auto foi descontinuado e não deve mais ser utilizado. Para execuções totalmente limpas e controladas, use --ignore-user-config / --ignore-rules.


05 Tornando a saída legível por máquina: a dupla --json e -o

A Seção 03 resolveu o problema de "evitar que o resultado final seja poluído com ruídos", mas ainda há outro desafio: analisar a saída do Codex em texto puro via scripts pode ser complexo e instável. Por exemplo, se você precisar extrair informações estruturadas como "a execução foi bem-sucedida?", "quais comandos foram executados?" ou "quantos tokens foram consumidos", fazer isso a partir de texto em linguagem natural é ineficiente e sujeito a erros.

O Codex oferece duas ferramentas complementares, e é essencial que os iniciantes entendam que elas servem a propósitos diferentes.

O primeiro é o --json: ele transforma todo o processo em um fluxo de eventos legível por máquina. Ao adicionar a flag --json (que possui o alias equivalente --experimental-json), a saída padrão stdout deixa de ser um bloco de texto comum e se torna um fluxo de eventos JSON Lines (JSONL, onde cada linha é um objeto JSON independente). Assim, o Codex emite uma linha JSON a cada mudança de estado durante a execução.

Analogia: A diferença entre assistir a um show e receber um relatório detalhado com carimbos de data/hora. Executar sem a flag --json é como assistir ao show ao vivo — é excelente, mas depois você não saberia dizer exatamente em qual minuto cada apresentação começou. Usar a flag --json é como receber uma lista detalhada: horário de abertura, início de cada ato e encerramento. Cada etapa é estruturada individualmente, permitindo que seu programa leia e tome decisões linha por linha.

bash
codex exec --json "总结这个仓库的结构" | jq

Cada linha emitida é um objeto de evento. Os tipos de eventos incluem thread.started (início da thread), turn.started / turn.completed / turn.failed (início, conclusão ou falha de um ciclo de interação), item.* (ações específicas como execução de comando, modificação de arquivo, chamada de ferramenta MCP, pesquisa na web ou atualização de plano) e error. A estrutura básica se assemelha a esta (onde cada linha é um JSON independente):

jsonl
{"type":"thread.started","thread_id":"0199a213-81c0-7800-8aa1-bbab2a035a53"}
{"type":"turn.started"}
{"type":"item.completed","item":{"id":"item_3","type":"agent_message","text":"仓库包含 docs、sdk、examples 三个目录。"}}
{"type":"turn.completed","usage":{"input_tokens":24763,"output_tokens":122}}

Com essa estrutura, fica fácil para os scripts validar o sucesso ou falha da execução, extrair as ações realizadas e contabilizar o consumo de tokens através de campos bem definidos.

O segundo é o -o / --output-last-message: ele salva apenas a mensagem final separadamente. Em muitos casos, você não precisa de todo o histórico do processo, apenas do resumo final salvo em um arquivo para a etapa seguinte. Basta adicionar -o <caminho_do_arquivo> (ou a flag longa --output-last-message):

bash
codex exec "提炼项目元信息" -o ./summary.md

Há um detalhe importante na documentação oficial que costuma passar despercebido: o -o grava a mensagem final no arquivo especificado, mas continua enviando a saída normalmente para o stdout. Ou seja, ele não consome o stdout, permitindo que você continue passando a saída via pipe para outros comandos.

Qual deles escolher? A tabela a seguir ajuda a decidir:

O que você precisaQual usarFormato/Comportamento
Ler passo a passo cada ação do programa, validar sucesso/falha ou contabilizar o consumo--jsonO stdout se torna um fluxo de eventos JSONL
Apenas o resumo final salvo em um arquivo-o <path>A mensagem final é gravada no arquivo e continua sendo enviada ao stdout
Ambas as opções no CI--json + -o juntosO fluxo de eventos alimenta o programa e o arquivo armazena apenas o resumo final limpo

Esta última opção é a combinação ideal recomendada oficialmente para integração em CI — utilizar --json e --output-last-message em conjunto no CI fornece um progresso legível por máquina e um resumo em linguagem natural ao mesmo tempo.

Eu configurei meu script diário de revisão de código exatamente dessa forma: o fluxo da flag --json alimenta um pequeno analisador para verificar se "problemas críticos foram detectados ou se a execução falhou" e decidir se envia um alerta; simultaneamente, o resumo Markdown gerado via -o é enviado diretamente para o canal da equipe como "Resumo da Revisão de Hoje". Com uma única execução, temos os dados estruturados para a automação e o texto limpo para a equipe, sem a complicação de tentar extrair trechos de blocos de texto desestruturados.

Existe ainda o parâmetro avançado --output-schema: forneça a ele um arquivo JSON Schema para garantir que a resposta final seja estruturada exatamente com os campos definidos (por exemplo, um formato fixo contendo "nome_do_projeto + lista_de_linguagens"), fornecendo dados previsíveis e consistentes para programas seguintes. Quando precisar integrar dados estruturados em etapas sequenciais, vale a pena explorar esse recurso; por enquanto, basta saber de sua existência.

💡 Resumo em uma frase: A flag --json transforma a saída padrão em um fluxo de eventos JSONL (como um relatório detalhado para leitura do programa, validação e métricas de uso), enquanto -o / --output-last-message salva o resumo final em um arquivo sem interromper a transmissão para o stdout; a recomendação oficial para CI é combinar ambos para obter dados estruturados e legíveis de uma só vez.


06 Pipe do stdin: passando a saída do comando anterior diretamente para o Codex

Até aqui você já aprendeu a "redirecionar a saída do codex exec para outras etapas". Agora, vamos ver o oposto — como alimentar o codex exec usando a saída de um comando anterior? É aqui que entra o pipe do stdin (entrada padrão), que é uma das formas mais práticas de integrar o codex exec ao fluxo de trabalho no terminal.

Por que isso é necessário? Em cenários reais, é comum "Obter dados brutos primeiro e, em seguida, pedir para o Codex analisá-los": logs de falhas de build, respostas in JSON de requisições de API ou logs gerados por pipelines de CI... Em vez de copiar e colar manualmente na interface interativa, você pode enviar tudo de uma vez por um pipe na linha de comando.

Há um ponto de confusão comum para iniciantes, mas a documentação divide o assunto em duas abordagens fáceis de entender: se você escreve a instrução e usa o pipe para enviar os dados como contexto → use "prompt + pipe"; se todo o prompt é gerado dinamicamente pelo comando anterior → use codex exec -.

Analogia: Duas maneiras de delegar uma tarefa ao seu assistente. No primeiro caso, você diz verbalmente "por favor, organize esses documentos em uma planilha" e entrega uma pilha de papéis — a instrução é falada e os documentos servem como anexo (prompt + pipe). No segundo caso, você entrega um bilhete contendo todas as instruções detalhadas e diz "siga o que está escrito aqui" — tanto a instrução quanto o conteúdo estão no papel (codex exec -). Ambas as formas são válidas; a escolha depende de a instrução ser escrita na hora ou vir pronta do comando anterior.

Abordagem 1: Prompt + Pipe (Você escreve a instrução, a saída do pipe serve como contexto)

Use esta opção quando você já sabe o que quer fazer e precisa apenas passar o resultado de um comando como material de suporte. A regra oficial é bem clara:

Se o stdin for enviado via pipe e você também fornecer um prompt como argumento, o Codex tratará o prompt como a instrução principal e usará o conteúdo do pipe como contexto adicional.

Exemplo típico — quando a compilação ou os testes falham, envie a saída do erro via pipe para analisar a causa raiz:

bash
npm test 2>&1 \
  | codex exec "总结失败的测试,提出最小改动的修复方案" \
  | tee test-summary.md

Resultado esperado: Toda a saída de npm test (com 2>&1 unificando o erro à saída padrão) é enviada como contexto para o Codex, utilizando a sua frase como a instrução principal; o resumo do Codex é exibido na tela e simultaneamente gravado em test-summary.md. Esse comando em linha única acelera imensamente o diagnóstico de erros de build comparado a copiar e colar os logs.

Outro exemplo é passar as últimas linhas de um log para análise da causa raiz:

bash
tail -n 200 app.log \
  | codex exec "找出最可能的根因,引用最关键的几条报错,给出接下来三步排查建议" \
  > log-triage.md

Abordagem 2: codex exec - (Usando o stdin como o prompt completo)

Quando o prompt completo é gerado dinamicamente pelo comando anterior — como um prompt armazenado em arquivo ou gerado via script — você não precisa digitar novas instruções; o conteúdo do stdin é consumido diretamente como o prompt completo. Se nenhum argumento de prompt for passado, o Codex lerá do stdin por padrão; para forçar esse comportamento e deixar a intenção explícita no script, utilize o caractere -:

bash
# 把一个文件里的内容当成整个提示词
cat prompt.txt | codex exec -
bash
# 用脚本现拼一个完整提示词,再整个喂进去
printf "用 3 条要点总结这段错误日志:\n\n%s\n" "$(tail -n 200 app.log)" \
  | codex exec -

Quando o caractere - é indispensável? Sempre que você armazenar o prompt em um arquivo, construir o prompt usando scripts shell ou unir a saída de um comando em tempo real com instruções antes de enviar tudo ao Codex — esses são os cenários ideais para o codex exec -.

Eu mantenho alguns arquivos de modelo de prompt (como um prompt padrão para revisão de PR) e executo cat modelo.txt | codex exec - quando necessário. Dessa forma, se precisar ajustar a instrução, altero apenas o arquivo de texto sem precisar modificar o script. A separação entre instruções e scripts traz muito valor em trabalhos de equipe.

💡 Resumo em uma frase: Ao enviar dados para o codex exec, observe a origem das instruções: se você escreve a instrução e os dados do pipe servem como contexto, use "prompt + pipe" (como explicar a tarefa verbalmente e entregar a papelada); se o prompt completo é gerado pelo comando anterior, use codex exec - (como entregar uma folha com todas as instruções de execução prontas).


07 Continuando de onde parou: codex exec resume

O modo não interativo não significa que a execução é estritamente de via única. Em alguns fluxos, você pode querer dividir o processo em duas etapas: primeiro pedir uma análise e, depois, fazer modificações com base nesse resultado. Esse fluxo de trabalho em duas fases pode ser encadeado usando o subcomando resume.

Analogia: Uma corrida de revezamento. Quando o primeiro corredor completa sua etapa (a primeira execução do codex exec), ele passa o bastão, e o segundo corredor continua correndo a partir desse ponto (codex exec resume). Não há necessidade de reiniciar a corrida, a execução continua exatamente com o contexto anterior. Sem o resume, você teria que retransmitir todas as conclusões da primeira etapa, consumindo mais tokens e correndo o risco de perder detalhes importantes.

bash
# 第一阶段:先让它找问题
codex exec "审查这处改动有没有竞态条件"

# 第二阶段:接着上一次,让它修掉刚找到的问题
codex exec resume --last "把你发现的竞态条件修掉"

A flag --last significa "continuar a partir da sessão mais recente no diretório de trabalho atual". Se preferir retomar uma sessão específica, basta fornecer o ID da sessão:

bash
codex exec resume <SESSION_ID> "继续上次的任务"

Dois detalhes adicionais: para pesquisar a sessão mais recente em todos os diretórios, use a flag --all; o prompt após o comando resume é opcional — você pode simplesmente retomar a sessão sem novas instruções ou enviar uma nova diretiva para dar continuidade.

Nota: Como mencionado na Seção 02, o uso da flag --ephemeral não salva os históricos de sessão no disco. Esse formato temporário de execução impossibilita o uso do resume (já que nada foi gravado). Evite usar --ephemeral se planeja criar fluxos de trabalho em duas etapas.

💡 Resumo em uma frase: O comando codex exec resume --last continua o trabalho a partir da sessão mais recente do diretório atual (como passar o bastão in uma corrida, evitando reprocessamento), podendo também especificar uma sessão via ID; execuções com a flag --ephemeral não podem ser retomadas.


08 Prática: Realizando o fluxo completo "rodar uma vez → coletar resultado → execução em lote"

Apenas ler a teoria não trará aprendizado prático. Abaixo está um fluxo de verificação mínimo que você pode executar em qualquer repositório Git (caso não tenha um, execute git init em um diretório vazio). Os comandos são reais e os resultados esperados para cada etapa estão documentados.

É necessário ter o Codex CLI instalado (consulte o Artigo 03 se precisar configurar) e executar os comandos em um repositório Git. Os comandos abaixo não exigem conexões de rede especiais. Os modelos de IA e saídas específicas dependem do que estiver configurado em seu ambiente local.

Etapa 1: Execução básica (somente leitura, sem alterar seus arquivos)

bash
codex exec "用一句话说清这个项目是干什么的"

Resultado esperado: Vários logs de progresso aparecerão na tela (enviados ao stderr) e, ao terminar, uma frase resumindo o repositório será exibida (enviada ao stdout), seguida do retorno automático para o prompt do seu terminal — sem abrir a interface interativa. O encerramento imediato comprova o funcionamento do modo não interativo.

Etapa 2: Salvar o resultado em arquivo para validar a separação de stdout / stderr

bash
codex exec "用一句话说清这个项目是干什么的" > result.txt

Resultado esperado: Você continuará vendo o progresso da execução na tela (pois o stderr não foi redirecionado), mas ao abrir o arquivo result.txt verá apenas a frase de resumo final, livre de logs de progresso. Isso valida a divisão de fluxos explicada na Seção 03 — onde o redirecionamento > captura somente o stdout.

Etapa 3: Adicionar a flag --json para visualizar o fluxo de eventos legível por máquina

bash
codex exec --json "列出这个项目里的文件类型"

Resultado esperado: O stdout se transforma in linhas de JSON (JSONL), iniciando com {"type":"thread.started",...}, listando ações do tipo item.* e terminando com turn.completed contendo o consumo de tokens. A visualização das linhas de JSON confirma a ativação do modo legível por máquina. (Se você tiver a ferramenta jq instalada, pode adicionar | jq no final do comando para formatar a saída de forma mais legível.)

Etapa 4: Utilizar a flag -o para salvar a mensagem final em um arquivo dedicado

bash
codex exec "用一句话总结这个项目" -o last.md

Resultado esperado: A frase de resumo continua sendo exibida na tela normalmente (o stdout permanece intacto) e, ao mesmo tempo, é gravada no arquivo last.md. Isso confirma que o -o grava no disco e mantém a saída ativa no stdout.

Etapa 5: Criar uma execução em lote — processando vários arquivos consecutivamente

Uma automação real em lote consiste em envelopar comandos codex exec individuais em um loop de shell. O exemplo a seguir gera uma frase descritiva para cada arquivo .md no diretório atual (usando --ignore-user-config para garantir execuções limpas e idênticas):

bash
for f in *.md; do
  echo "=== $f ==="
  codex exec --ignore-user-config "用一句话说明 $f 写的是什么"
done

Resultado esperado: O loop executa o codex exec para cada arquivo .md individualmente, imprimindo o nome do arquivo seguido do seu respectivo resumo. Esta é a base de uma "automação em lote sem supervisão" — combinando loops com o codex exec, sem necessidade de monitoramento humano.

Ao concluir essas cinco etapas, você terá executado o ciclo essencial do modo não interativo: "rodar uma vez → observar os canais de saída → extrair JSON → salvar em arquivo → envelopar em um loop". Integrar esse processo em novos scripts ou fluxos de CI segue a mesma estrutura, alterando apenas a instrução e adicionando --sandbox workspace-write para permitir modificações nos arquivos.

💡 Resumo em uma frase: O aprendizado prático é resumido em cinco etapas — executar o codex exec → direcionar com > para testar os canais → extrair logs estruturados via --json → salvar a mensagem com -o → criar automações com o loop for; executá-los constrói a memória muscular necessária para integrar o Codex em seus scripts.


09 Resumo

Este artigo explicou o modo não interativo do codex exec desde o propósito de sua criação até as estratégias para integrá-lo em scripts de automação em lote, destacando os erros de configuração mais comuns.

Salve a tabela a seguir contendo as diretrizes centrais do comando:

O que você deseja fazerComo executarPontos-chave
Executar uma tarefa não interativacodex exec "..." (atalho codex e)Conclui e encerra; não pausa para pedir aprovações
Salvar apenas o resultado limpo em arquivocodex exec "..." > out.mdO resultado vai para o stdout e os logs de progresso para o stderr; > captura apenas o resultado
Permitir modificações reais nos arquivosAdicionar --sandbox workspace-writeO modo padrão é somente leitura; ele não fará alterações a menos que permitido explicitamente
Obter o progresso em formato legível por máquina--jsonO stdout se torna um fluxo de eventos JSONL para leitura do programa
Salvar o resumo final em um arquivo-o <path>Grava no disco e mantém a saída no stdout; recomendado usar junto com --json no CI
Alimentar o comando com a saída anteriorPrompt + Pipe / codex exec -Depende se você escreve a instrução na hora ou se ela é gerada dinamicamente pelo pipeline
Continuar a partir da execução anteriorcodex exec resume --last "..."Ideal para pipelines em duas etapas; sessões com --ephemeral não podem ser retomadas

Agora você é capaz de: explicar quais cenários "sem supervisão humana" o codex exec resolve; entender por que a divisão entre "progresso no stderr e resultado no stdout" facilita o uso de pipes e redirecionamentos; diferenciar o papel das flags --json e -o e entender por que usá-las juntas em CI; lembrar-se da armadilha do valor padrão — o modo não interativo é somente leitura e requer a declaração explícita de --sandbox workspace-write para fazer modificações; bem como enviar dados via stdin usando as duas abordagens descritas e encadear etapas com o resume.

A lição mais importante: o codex exec não é uma "versão limitada do modo interativo", mas sim a ferramenta que transforma o Codex de um assistente interativo em um componente padrão que pode ser chamado por scripts, pipes e pipelines de CI — este passo é o que realmente abre as portas para a automação avançada.


O próximo artigo [29 Integração com Slack / Linear e SDK]: Você aprendeu a integrar o Codex em scripts e fluxos de CI pela linha de comando. No próximo artigo, mudaremos a abordagem — vamos integrá-lo com as ferramentas de colaboração do dia a dia: mencione-o com um @ no Slack para iniciar uma tarefa, atribua chamados automaticamente no Linear ou utilize o SDK para incorporar as capacidades dele diretamente em seu próprio software. Pense no seguinte: se o codex exec pode enviar resultados por pipe para o gh pr comment, quantas etapas manuais seriam eliminadas ao conectá-lo ao Slack ou a um gerenciador de chamados? Continuaremos essa conversa no próximo artigo.


Leituras recomendadas