Mac 终端里怎么用语音输入
在终端里打字久了会发现一件事:描述一个需求往往比敲命令本身更费劲。尤其是
Claude Code、Codex CLI 这类跑在终端里的 AI 工具流行之后,你输入的不再是
git commit,而是一整段话——"帮我把这个函数拆开,顺便把测试补上"。
这种时候说比打快得多。但终端恰恰是 macOS 上语音输入最不好使的地方。
为什么系统听写在终端里不好使
macOS 自带听写(连按两下 Control 触发)在备忘录、浏览器输入框里工作得很好, 到了 Terminal 或 iTerm2 就经常出问题:要么文字完全插不进去,要么插到了奇怪 的位置,要么识别完就没下文了。
这不是 bug,是架构差异。
系统听写把识别结果交给当前获得焦点的文本控件,走的是 macOS 的辅助功能
(Accessibility)接口。普通 App 用的是 NSTextField、NSTextView 这类标准
控件,系统知道光标在哪、该把字插在哪。
终端模拟器不是这样。Terminal、iTerm2、Warp、Alacritty 这些程序自己绘制字符 网格,把键盘输入直接转成字节流送给底层的伪终端(PTY)。它们对系统而言更像 一块画布,而不是一个文本框。系统听写找不到标准的插入点,自然就落空了。
同样的原因,跑在终端里的程序——Claude Code、Vim、各种 REPL——也都继承了这个 问题:它们处理的是字节流,不碰图形层的文本控件。
有些 AI 工具后来加了自己的语音功能,但那些入口通常绑在它自己的聊天界面上, 而且多数需要把音频传到服务器。换句话说,它解决的是"在这个产品里说话", 不是"在终端里打字"。SSH 到远程机器、或者你用的是另一个 CLI,就又回到原点。
几种可行的办法
1. 让工具模拟键盘输入
绕开"插入文本"这条路,改成"假装你在打字"。识别完成后,工具把文字作为键盘 事件发给系统,终端收到的和你真敲键盘没有区别。
这是目前在终端里最可靠的做法,因为它不依赖应用暴露任何文本接口——只要那个 窗口有焦点就行。代价是需要授予辅助功能和输入监听权限。
语音狗子 走的就是这条路:长按右 Option 说话,松开后文字落在光标处, 终端、编辑器、浏览器一视同仁。识别用的是本地模型,不联网、不需要 API Key。
2. 用带语音功能的终端或编辑器
一部分 AI 编辑器(Cursor、Zed 等)在自己的聊天面板里内置了语音输入。这条路 省事,但范围仅限那个面板——你没法用它在终端标签页里敲命令,也没法在浏览器 的 ChatGPT 输入框里用。
3. 先转写到别处,再粘贴过去
用任意听写工具(包括系统听写)在备忘录或文本编辑器里说出来,然后复制粘贴 到终端。听上去笨,但在只偶尔需要的场景下完全够用,而且零成本。
4. 自己接云端 ASR
把 Whisper 或各家云端语音 API 接成一个脚本,配合快捷键触发。灵活度最高, 适合愿意折腾的人。要考虑的是密钥管理、网络延迟,以及音频是否离开本机。
怎么选
| 适合 | 要注意 | |
|---|---|---|
| 模拟键盘输入的工具 | 终端为主、想全局可用 | 需要辅助功能权限 |
| 编辑器内置语音 | 只在那一个面板里说话 | 出了那个面板就没有 |
| 转写后粘贴 | 偶尔用一次 | 多两步操作 |
| 自建 ASR 脚本 | 想完全掌控 | 要自己处理密钥和延迟 |
如果你的主场景就是终端——写 prompt 给 Claude Code、敲长命令、在 SSH 会话里 记东西——那么第一类是唯一不用来回切窗口的办法。
权限这一关绕不过去
无论用哪个模拟键盘输入的工具,macOS 都会要求两项授权:
- 辅助功能(系统设置 → 隐私与安全性 → 辅助功能):允许程序代你发送 键盘事件
- 输入监听(同一位置 → 输入监听):允许程序知道你按住了哪个键
这两项权限的能力确实很大,所以值得花一分钟确认:这个工具是否把音频上传、 是否开源或至少说明了数据流向。完全本地运行的方案在这一点上风险小得多—— 音频从来没离开过你的机器。
按住了没反应?多半是「安全键盘输入」
这是终端场景独有的一个坑,而且表现是完全静默——没有报错,没有提示, 按住键就是没反应,很容易以为是工具坏了。
Terminal.app 的菜单里有一项「安全键盘输入」(Secure Keyboard Entry)。 开启后,macOS 会进入 Secure Event Input 状态,停止向第三方程序的事件监听 (event tap)派发按键事件。这个机制本身是对的:它防止别的程序偷看你在终端 里敲的密码。
代价是,所有靠监听按键来触发的工具——包括语音输入类——在那个终端获得焦点时 都收不到你的按键。于是你按住右 Option,什么都不会发生。
怎么确认和解决:
- 打开 Terminal → 顶部菜单「终端」→ 看「安全键盘输入」有没有打勾
- 取消勾选,再试一次语音输入
- iTerm2 在「Preferences → General → Secure Keyboard Entry」有同名选项
要权衡的是:关掉它意味着其他程序理论上能监听你在终端里的输入。如果你经常 在终端里直接敲密码(而不是用密码管理器或 SSH key),保持开启更稳妥, 这种情况下换用"转写后粘贴"的办法。
这个限制对所有依赖 event tap 的工具一视同仁,语音狗子也不例外。 它目前不会主动提示这一点——按住没反应时,先查这个开关。
一个实际的用法
装好之后比较顺手的节奏是这样的:
# 在终端里起 Claude Code
$ claude
# 光标停在输入行,长按右 Option
> 「把 src 下所有组件的 PropTypes 换成 TypeScript 类型,一个文件一个 commit」
# 松开,文字落在光标处,检查一眼再回车
把"说完"和"回车"分成两步,是个值得保留的习惯。语音识别总有出错的时候, 而终端里的命令一旦执行就收不回来。
接着看
这篇讲的是「在终端里能不能说话」这个总问题。几个具体场景另有展开:
- 按住了完全没反应,而且权限都给了 —— 多半是终端的安全键盘输入在挡, 它的完整机制和确认方法在这里
- 给 Claude Code、Codex CLI 口述需求 —— 口述 prompt 的实际写法,包括该说什么、不该念什么
- 口述时音频去了哪里 —— 本地识别和服务端转写的区别,以及它到底保护了什么
- SSH 到远程机器、或在 tmux 里干活 —— 远程场景为什么是另一回事
- 只想先把系统自带的用明白 —— macOS 听写怎么开,边界在哪