---
title: "`cat file | claude -p` — 处理管道内容"
description: "把日志、diff、接口返回直接喂给 claude -p：标准输入与提示词如何拼接、JSON 结果怎么接、退出码和权限在脚本里怎么管。"
updated: 2026-11-13
canonical: https://docai.cc/learn/process-piped-input/
markdown_mirror: https://docai.cc/learn/process-piped-input.md
---
## 一条管道能省掉多少复制粘贴

线上日志几万行，你只想知道哪几类报错最该先修。改完代码，你想在提交前听一遍不同意见。接口返回一大段数据，你想要一句人话总结。这些素材本来就在文件或命令输出里，复制进对话框既慢，也容易漏掉关键行。

`claude -p` 是单次执行模式：给出任务，拿到结果，进程结束，不进入交互界面。它同时读取标准输入，所以 shell 的管道可以直接把内容送进来。

```bash
grep -i "error" logs/app.log | claude -p "按出现频率归类这些报错，指出最该先修的三类"
```

左边筛选，右边判断。整节课讲的就是这条分工线。

## 它收到的到底是什么

管道内容不是附件，而是和你写在命令里的那句话拼成同一段输入。两件事因此要交代清楚：

- 指令要具体：看什么、按什么标准排、输出几句、用什么语言。
- 素材要说明：这是哪个时间段的日志、哪些行可以忽略、字段含义是什么。

素材里夹着代码或表格时，加一行分隔，让它知道正文从哪开始。内容太长就先裁剪：只取相关时段、只留报错行、去掉重复堆栈。省下的 token 是实打实的成本，更能减少它被无关内容带偏的机会。上下文如何计量，见[上下文窗口](/concepts/context-window/)。

## 三个马上能用的组合

**审查改动。** diff 直接进管道，提示词只写关注点：

```bash
git diff | claude -p "只报会改变运行结果的问题，按文件分组；格式和命名不要提"
```

**整理提交记录。** 让它输出纯文本，直接贴进发布说明：

```bash
git log --oneline v1.2..HEAD | claude -p "按新增、修复、其他分三段整理，不要补充记录里没有的内容"
```

**读接口数据。** 先取数，再让它挑异常：

```bash
curl -sS https://example.com/api/stats | claude -p "找出偏离日常范围的指标，各用一句话解释可能原因"
```

三个例子的结构一致：命令负责取数，提示词负责定性，输出约束成你要的形状。路径和地址都要换成你自己的；先拿一小段样本验证提示词，确认输出可用，再放到全量数据上跑。

## 让结果能被脚本接住

给人看的回答是段落，给程序用的回答要结构化。加 `--output-format json`，再从中取正文。返回体里除了 `result`，通常还有 `is_error`、`total_cost_usd`、`duration_ms` 这类字段；字段名随版本变化，写解析前先打印一份看结构。

```bash
report=$(grep -i "error" logs/app.log | claude -p "归并同类报错，按影响排序" --output-format json)
printf '%s\n' "$report" | jq -r '.result'
```

两条原则：先看 `is_error`、再校验收到的结构，最后才取 `result`；解析失败按错误处理，不要静默变成空字符串。需要边生成边处理时，可以选流式输出，把逐条事件交给下游；只是落盘的话，一次性结果更省心。

## 脚本里的四条纪律

1. **看退出码。** 成功为零，失败非零。紧跟判断，或在脚本开头设置遇错即停。
2. **设超时。** 外层用 `timeout` 包住，别让一次卡住的调用拖死整条流水线。
3. **管权限。** 单次模式不等于放开写权限；改文件、跑命令仍受权限设置约束。无人值守时先缩小工作范围，再决定放到多宽。
4. **记账。** 每次调用的耗时与费用写进日志；跑批量前先用一条样本估算总量。

批量处理时逐条循环、逐条检查返回值。前一条失败，就不要继续覆盖后面的产物。要重试就限次数、拉长间隔，别在故障时空转。

## 一个最小可用的检查脚本

```bash
#!/usr/bin/env bash
set -euo pipefail
log="logs/app.log"
out=$(grep -i "error" "$log" | claude -p "归并同类报错，给出三条最优先的修复建议")
printf '%s\n' "$out"
```

注意 `grep` 没匹配到内容时退出码非零，配合 `set -o pipefail` 会让脚本提前结束；要么在 `grep` 后加 `|| true`，要么把「没有报错」当成正常分支，先判断匹配结果再决定是否调用。

先在只读场景把它跑顺，再考虑加入写文件、发通知这些动作。判断标准很朴素：单独跑十次，结果稳定、退出码可信，才值得固化。

## 一次处理一批文件：完整脚本

单条命令能跑通，不代表批量任务安全。下面这个脚本处理一个目录里的 Markdown 文件，每个文件单独调用一次，产物写入 `out/`，任何一份失败都不会拖垮其余文件：

```bash
#!/usr/bin/env bash
set -uo pipefail

in_dir="docs"
out_dir="out"
mkdir -p "$out_dir"

failed=0
for f in "$in_dir"/*.md; do
  [ -e "$f" ] || { echo "没有匹配到文件" >&2; exit 1; }
  name=$(basename "$f" .md)
  tmp="$out_dir/$name.txt.part"
  if claude -p "只输出三条要点，每条一行，不加标题和前言" \
       < "$f" > "$tmp"; then
    mv "$tmp" "$out_dir/$name.txt"
    echo "完成: $f"
  else
    rm -f "$tmp"
    echo "失败: $f" >&2
    failed=1
  fi
done

exit "$failed"
```

几个细节值得照搬：

- 先写临时文件，成功后再改名，避免下游读到半截结果。
- 失败计数而不是立刻退出，批处理时你希望知道总共有几份没成功。
- 没有匹配到文件时明确报错；否则循环体一次都不执行，脚本会「成功」退出。
- 产物目录与源目录分开，重复运行也不会覆盖原文。

跑之前先拿一份样本试提示词：

```bash
claude -p "只输出三条要点，每条一行，不加标题和前言" < docs/示例.md
```

确认输出形状稳定，再把同一句话放进循环。若每份文件需要不同的指令，就在循环里按文件名分支，不要把所有规则塞进一条超长提示词。

## 常见故障：现象、原因与处理

| 现象 | 为什么 | 怎么办 |
| --- | --- | --- |
| 管道左边没输出，右边仍返回一段泛泛而谈 | 上游命令没匹配到内容，管道默认不传递失败状态 | 先看上游退出码与行数；空输入时直接跳过调用 |
| 提示词的要求被素材淹没 | 标准输入与命令行文字拼成同一段，长素材占了大部分注意力 | 提示词写具体约束，素材前后加分隔行，内容太长先裁剪 |
| JSON 解析报错或取到空值 | 输出里混入解释文字，或字段名与当前版本不同 | 用 JSON 输出模式，先打印整体结构再取字段，并检查错误标记 |
| 脚本在无人值守时停住 | 某一步需要人工确认权限，单次模式也不会自动同意 | 只读任务先跑；确需写操作时缩小目录范围，并按当前版本配置权限 |
| 跑了一夜，账单超出预期 | 循环次数乘以单次费用，没有先估算 | 先用一份样本记录耗时和费用，再乘总数；日志里保留每次的用量字段，估算方法见[费用估算](/learn/estimate-cost/) |
| 长日志让回答只覆盖开头和结尾 | 输入超过上下文容量，中段被挤出 | 用 `head`、`grep` 或时间窗口先缩小范围，分段处理再汇总 |

还有三类任务不适合走管道。需要来回追问、逐步改稿的，应该用交互模式；需要对同一个仓库连续做多处修改的，单次调用每次都要重新建立上下文，效率反而低；材料里含密钥、客户隐私或未脱敏数据的，不要直接送进命令行，先脱敏或改用受控环境。

下一节处理另一半问题：任务做到一半，怎么接着上次的上下文继续，见[继续最近的对话](/learn/continue-last-conversation/)。
