---
title: "多行输入"
description: "回车一敲就发送，代码刚贴一半就碎成几条消息。几种多行写法各自适合什么场景，以及粘贴失效、内容被截断时按什么顺序排查。"
updated: 2026-11-13
canonical: https://docai.cc/learn/multi-line-input/
markdown_mirror: https://docai.cc/learn/multi-line-input.md
---
## 一行没写完就发出去了

你想让它改一段函数，先写要求，再粘代码。第一次回车，要求单独成了一条消息；剩下几行又各自成条。对话被切碎，它只能反复问你想干嘛。

这不是它笨，是输入框的默认规则：回车等于发送。想一次给一整段，就得让换行不触发提交。下面几种做法，从最顺手到最稳排列。

先把选择标准说清楚，后面就不用来回试：

| 场景 | 首选写法 | 原因 |
| --- | --- | --- |
| 本地终端，写三五行要求 | Shift 加回车 | 最接近普通编辑器的手感 |
| 终端不认 Shift 加回车 | 反斜杠加回车或 Ctrl+J | 不依赖终端识别组合键 |
| 远程登录、老终端 | 三引号模式 | 只用到普通字符，兼容性最好 |
| 几十行以上的提示词 | 文件输入 | 可编辑、可复用、可进版本库 |
| 脚本或批处理 | heredoc 或管道 | 调用和内容写在一处，复制就能跑 |
| 从别处复制一大段 | 括号粘贴 | 一次送入，保留换行 |

## 顺手改键：Shift 加回车

按住 Shift 再按回车，光标下移，消息不发出。写完后单独按一次回车提交。

问题出在终端。有的终端原生支持，有的会把组合键当成普通回车。官方列出的原生支持名单是 iTerm2、WezTerm、Ghostty、Kitty、Warp 和 Windows Terminal；VS Code、Cursor、Zed、Alacritty 0.16 以前的版本要跑一次 `/terminal-setup`；GNOME Terminal 和 JetBrains 系不支持。macOS 上把 Option 设成 Meta 后，Option 加回车也能换行。

一份更细的对照，方便你判断手里这个终端该怎么办：

| 终端 | 是否原生支持 | 备注 |
| --- | --- | --- |
| iTerm2 | 支持 | 到 Profile 的 Keys 里确认没被别的动作占用 |
| Terminal.app | 不在原生支持名单 | 用 Ctrl+J，或把 Option 设为 Meta 后用 Option+Enter |
| Windows Terminal | 较新版本支持 | 老版本升级后再试 |
| GNOME Terminal | 不支持 | 用 Ctrl+J 或三引号 |
| Konsole | 支持 | 版本差异较大，以实测为准 |
| Alacritty | 新版本支持 | 旧版本需要终端配置 |
| WezTerm | 支持 | 通常开箱可用 |
| 老版 PuTTY | 不支持 | 按下去等同直接提交 |
| SSH 客户端 | 取决于配置 | 先在远端试一次再决定写法 |

终端不认时的备用键位，按顺序试：Ctrl+J 最通用，它发送的是换行控制字符，不依赖终端把组合键翻译成特殊序列；Alt+Enter 在部分环境可用；macOS 上可以试 Option+Enter。三个都不行，直接跳到三引号模式。

## 反斜杠加回车：所有终端都能用

在行尾敲一个反斜杠，再按回车，输入框里插入一个换行，消息不发出。这个写法不依赖终端对 Shift 加回车的支持，SSH 到老服务器上也一样。敲完最后一行，单独按一次回车提交。

反斜杠必须是这一行的最后一个字符，后面多一个空格就不生效。Windows 路径也用反斜杠，粘贴代码时容易在行尾多带一个，发送前扫一眼。`Ctrl+J` 也能插入换行，它不依赖终端的键位配置，和反斜杠一样能绕开 Shift 加回车的兼容问题。

这个写法适合短稿：每行末尾多敲一个字符，写十行还能接受，写五十行就烦了。行数一多，换文件输入。

## 三引号多行模式：一个开关包住整段

在输入框单独敲三个双引号，按回车，会进入一个多行状态。之后每次回车都只换行，不再提交，直到你再单独敲一行三个双引号，再按一次回车，整段才发出去。

```text
"""
请重构下面的代码，要求：
1. 把回调改成 async/await
2. 错误用 try/catch 处理
3. 补上 JSDoc 注释

function fetchUser(id, callback) {
  db.query('SELECT * FROM users WHERE id = ?', [id], (err, rows) => {
    if (err) return callback(err);
    callback(null, rows[0]);
  });
}
"""
```

它最大的好处是兼容性：只用普通字符，不依赖终端识别任何组合键，远程登录、老式终端、网页终端都能用。代价是两头的开关要记牢，而且不能随手在里面再写三个双引号。

和三引号相比，Shift 加回车更像「随用随走」：不用记开关，也不怕内容里有特殊符号，但对终端有要求。两个方案怎么选，可以看这张表：

| 维度 | 三引号模式 | Shift 加回车 |
| --- | --- | --- |
| 终端要求 | 几乎没有 | 要看终端是否识别 |
| 视觉提示 | 提示符可能变化 | 通常没有变化 |
| 写错了想改 | 还在多行状态里，可以继续改 | 同样可以改 |
| 适合的场景 | 远程会话、陌生终端 | 本地开发、键位顺手 |
| 粘贴整段代码 | 适合，先开三引号再粘 | 取决于括号粘贴是否生效 |

### 两个常见坑

第一个坑是忘了收尾。敲了回车没反应、提示符也变了样，多半是还停在三引号状态里。补一行单独的三引号，或者按 Ctrl+C 取消这一轮输入，就能退出来。

第二个坑是内容本身带三引号。比如让它看一段 Python 代码，里面正好有文档字符串，那三个引号会被当成结束标记，后半段直接漏掉。这种情况换成 Shift 加回车，或者把代码存成文件让它自己读，别和三引号较劲。

## 长内容放进文件

提示词几百行时，终端里改起来很别扭。存成文件，让启动命令读进去：

```bash
claude "读取 task.md，按里面的步骤执行"   # 进入对话，让它自己读文件
claude -p < task.md                       # 把文件内容当提示词，跑完就退出
```

只想拿一次结果、还要接进脚本，用 `-p`。文件输入还有个好处：提示词能进版本库。改了什么、哪次改动让结果变差，翻记录就知道。启动前用编辑器通读一遍，错别字和漏掉的约束都能提前拦住。

两种读法的差别值得分清。第一种是把文件路径告诉它，由它自己决定什么时候读、读哪几段，适合大文件；第二种是把文件内容直接当第一条消息送进去，适合中小文件、要求一次说清的任务。文件很大时优先第一种，别把几万字一次性塞进上下文。

想让别的命令的输出直接当输入，用管道：

```bash
git diff | claude -p "按风险排序，指出这次改动最可能出问题的地方"
```

管道送来的内容和命令行里写的提示词会拼在一起送进去：命令在前，文本在后。写的时候要意识到这一点，别在提示词里假设它只看到了你打的那句话。

脚本里写长提示词，heredoc 更整齐。定界符加单引号，里面的 `$` 和反引号就不会被 shell 展开：

```bash
claude -p <<'PROMPT'
检查依赖清单：
1. 列出无人维护的包
2. 标出跨大版本升级的项
3. 给出升级顺序
只输出清单，不要执行安装。
PROMPT
```

定界符不加引号时，shell 会替换里面的变量，这既是功能也是风险：想传项目路径，可以写 `$PROJECT_DIR`；但提示词里如果本来就有美元符号、反引号或反斜杠，就会被 shell 先处理一遍，内容变形。除非确实要传变量，否则一律用带引号的写法。

heredoc 适合把提示词和调用写在同一个脚本里，复制走就能跑；缺点是改起来不如独立文件方便。需要反复调整措辞的提示词，还是存成独立文件。

## 粘贴被拆开、内容被截断

现代终端支持括号粘贴，多行内容一次进入输入框。粘贴后仍被逐行发送，先确认终端类型和配置是否启用；临时办法是把内容先存成文件，用 `claude -p < task.md` 送进去，别在键位上反复试。

快捷键也可能按错。Windows 终端里粘贴常用 Ctrl+Shift+V，macOS 用 Cmd+V，有的终端还提供右键或菜单。按下去没反应时，先确认你用的是终端的粘贴，而不是编辑器的。

另有三种截断来源。单行过长，某些终端有上限，拆行或改文件；复制来的内容夹带控制字符，先存文件看清再读；内容超出模型能处理的范围，别硬塞，给它路径让它自己读。最后一种最值得养成习惯：贴一整份文件，不如告诉它文件在哪，省 token 也更准，见[上下文窗口](/concepts/context-window/)。

### 粘贴变逐行提交

症状是每粘一行就发出去一条。原因是终端没有开启括号粘贴，输入框把内容里的换行都当成了回车。先看终端类型变量，正常的取值形如 xterm-256color、screen-256color 或 tmux-256color；再查本机的行编辑配置里有没有开启括号粘贴。tmux 里还要确认它没有把剪贴板事件吞掉。排查不出来时不要纠缠，直接把内容存成文件，用输入重定向送进去，三秒解决。

### 长提示词只收到前半段

症状是贴了几千字，模型只回应开头一小段。常见原因有四个，按这个顺序查：

1. 终端单行长度限制。有的环境一行最多几千字节，超出的部分被截掉。把内容拆成多行再贴。
2. 夹带了看不见的控制字符。从网页或文档复制时常带控制序列，可用 `cat -A` 查看，出现大量 ^[ 一类的记号就是有问题；再用 `tr` 过滤掉控制字符，存成干净文件。
3. 超出上下文容量。几万 token 的日志不适合整段贴，先用 `/compact` 腾空间，或者拆成几批，最好让它按路径自己读。
4. 代理或网络层截断。只在个别人机器上复现时，先怀疑网络链路。

这四类的共同解法都是「别在输入框里硬扛」：内容进文件，路径给它，读哪段由它决定。具体怎么让它按需读文件，见[让它自己读文件](/learn/let-model-read-files/)。

### 想把提示词和代码分开

粘贴代码后它把要求和代码搅成一团来理解，最省事的修法是用代码围栏明确边界：先写要求，空一行，再贴三个反引号加语言名，接着贴代码，最后用三个反引号收尾，末尾再补一句问题。围栏本身就是给模型的信号，比在正文里说「下面这段是代码」更清楚。

## 一份可以直接用的任务书

```text
请读取 src/old_parser.py 并重构：
- 改成函数式写法
- 补类型标注
- 保留原有说明文字
- 每改完一个函数先停，等我确认

约束：不改公开接口，不新增依赖。
```

用 `claude -p < task.md` 跑一次，或进入对话后说「读取 task.md，先复述计划」；先让它只读、复述，确认无误再放行修改。任务书里把「先做什么、停在哪、什么不能动」写清楚，比堆形容词有用。它每完成一段就停下来，你能及时纠偏，不会一口气改完十个文件才发现方向错了。

还需要批量处理多个文件时，可以把任务书和循环写进一个脚本：遍历目标文件，对每个文件调用一次非交互模式，把结果写到新文件里，处理完再人工抽查几份。批量任务的提示词更要固定，因为没人会逐条盯着输出。这条路线和[批量处理文档](/learn/batch-document-processing/)里的做法是同一套思路。

## 故障排查：症状、原因、处理

| 症状 | 原因 | 处理 |
| --- | --- | --- |
| Shift 加回车直接发送 | 终端不识别这个组合 | 换 Ctrl+J 或反斜杠加回车 |
| 粘贴后逐行发出 | 括号粘贴未开启 | 存文件输入，或改终端配置 |
| 三引号里回车也不发送 | 正常，说明还在多行状态 | 补一行三引号收尾 |
| 三引号内容缺了后半段 | 内容里自带三引号，提前闭合 | 改用 Shift 加回车或文件 |
| 多行状态退不出去 | 忘了收尾符 | 按 Ctrl+C 取消本轮输入 |
| 长文只收到开头 | 行长度限制、控制字符或上下文超限 | 按上面四步排查 |
| heredoc 里的变量没替换 | 定界符带了单引号 | 需要变量时去掉引号，但注意特殊字符 |
| 管道内容和提示词混在一起 | 两者本来就会拼接 | 调整提示词，明确指代对象 |

取消输入记住一个键就够：Ctrl+C 按一次只中断这次输入，不会退出整个工具。Esc 也能清掉当前草稿，选哪个看手习惯。

### 边界：什么情况下别用多行输入

不是所有任务都值得凑成一大段。需要来回确认的探索性任务，一句一句问反而更快；改一处小错，也不必开三引号或写文件。真正适合长输入的，是需求已经想清楚、约束需要一次交代完整的任务。

还有一个容易忽略的边界：多行输入解决的是「怎么送进去」，不解决「送进去什么」。把五十行日志整段贴进去，不如先筛出报错前后二十行；把整个仓库贴进去，不如给出路径和关注点。输入方式越省事，越容易把无关内容也带进去。写之前先删掉一半，往往比换一种输入方式更有效。

键位和写法只是入口，真正的效率来自把要求写完整、一次说清。下一节回到操作本身，把常用按键练熟：[命令历史](/learn/command-history/)；想系统对照终端按键，看[键盘快捷键](/learn/claude-code-shortcuts/)。
