【2026-3-10官方已修复该问题,此贴终结】尝试解决 ClaudeCode在Windows环境下copy乱码问题

2026-04-11 11:231阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐
问题描述:
起因

本来只是个小bug,不影响使用,但是最近写文档还挺多的,这个功能对我比较实用

问题描述

Claude Code 的 /copy 命令在 Windows(包括 WSL)上复制含中文、日文、韩文、越南语等非 ASCII 字符的文本时,粘贴结果为乱码(mojibake)。macOS 和 Linux 用户不受此问题影响。

相关 Issue: #22346(OPEN, stale)、#27709(closed as duplicate)

测试环境: Windows 10/11, Claude Code v2.1.x, pwsh 7


为什么会产生这个问题?

Claude Code 在不同平台使用不同的剪贴板命令(cli.js 中定义):

{ macos: ["pbcopy"], // ✅ 原生支持 UTF-8 linux: ["xclip -selection clipboard", "wl-copy"], // ✅ 原生支持 UTF-8 wsl: ["clip.exe"], // ❌ 不支持 UTF-8 windows: ["clip"], // ❌ 不支持 UTF-8 }

当用户执行 /copy 时,执行链路如下:

用户在 pwsh 中运行 claude (Node.js 进程) │ ├─ /copy 触发剪贴板写入 │ ├─ Node.js 调用 execa("clip", { input: text, shell: true }) │ │ │ ├─ Node.js 内部将 JavaScript 字符串 (UTF-16) 转为 UTF-8 字节流 │ │ 写入子进程的 stdin │ │ │ └─ shell: true → 使用 process.env.comSpec (= cmd.exe) │ │ │ └─ 实际执行: cmd.exe /d /s /c "clip" │ │ │ └─ clip.exe 从 stdin 读取字节流 │ │ │ └─ ❌ clip.exe 使用系统 OEM 代码页 (如 CP437/CP936) │ 解读字节流,而非 UTF-8 │ └─ 结果:UTF-8 字节被按错误编码解读 → 乱码

核心矛盾:

环节 编码
Node.js stdin 输出 UTF-8
clip.exe stdin 读取 系统 OEM 代码页(GetOEMCP(),通常为 CP437 或 CP936)

这个编码不匹配是乱码的直接原因。

为什么不能通过 ~/.bashrc$PROFILE 修复?

我们测试了以下方案,均无法解决此问题:

~/.bashrc 中设置 chcp 65001

.bashrc 只在 Claude Code 的 Bash Tool(执行 shell 命令的工具)调用时被 source。而 /copy 是 Node.js 进程直接 spawn cmd.exe 子进程,完全不经过 bash:

/copy 的路径:Node.js → cmd.exe → clip.exe (不经过 bash) Bash Tool: Node.js → bash (source .bashrc) (跟 /copy 无关)

在 PowerShell $PROFILE 中设置 chcp 65001

chcp 65001 改变的是当前 console 会话的代码页,但 clip.exe 读取 stdin 时使用的是系统 OEM 代码页(通过 GetOEMCP() 获取),这是系统级全局设置,chcp 无法改变它。

那为什么 chcp 65001 >nul & clip 在同一个 cmd 会话里就能工作?

因为 chcp 65001 在同一个 cmd.exe 会话中同时改变了该进程的 stdin 处理方式。clip.exe 作为同一会话的下一个命令直接执行时,继承了这个修改。但从外部(pwsh、bash)设置的 codepage 无法传递到 Node.js 随后 spawn 的 cmd.exe 进程中。

PowerShell $input | Set-Clipboard

PowerShell 的 $input 自动变量从 stdin 读取时,同样不使用 UTF-8 编码,即使在 pwsh 7 中也是如此。经 Node.js 模拟测试验证,结果仍为乱码。


解决方案

以下提供两种修复方案,任选其一即可。

方案一:补丁脚本(推荐)

直接修改 cli.js 中的剪贴板命令,在调用 clip 前先用 chcp 65001 切换到 UTF-8 代码页。

优点: 最精准,只改一个字符串,零副作用,不影响系统中任何其他软件
缺点: 每次 Claude Code 更新后需重新执行

使用方法

  1. 将下方脚本保存为 fix-claude-copy.mjs
  2. 执行补丁:

node fix-claude-copy.mjs

  1. 重启 Claude Code 即可生效

补丁内容

脚本会自动定位 cli.js 并做以下替换:

# Windows windows:["clip"] → windows:["chcp 65001 >nul & clip"] # WSL wsl:["clip.exe"] → wsl:["cmd.exe /c 'chcp 65001 >nul & clip'"]

完整脚本代码

#!/usr/bin/env node /** * Claude Code /copy 中文乱码修复补丁 * * 问题: Windows/WSL 上 /copy 命令使用 clip.exe,不支持 UTF-8 stdin,导致中文乱码 * 修复: 在调用 clip 之前先用 chcp 65001 切换到 UTF-8 代码页 * * 用法: node fix-claude-copy.mjs * 每次 Claude Code 更新后需重新执行 */ import { readFileSync, writeFileSync } from 'fs'; import { execSync } from 'child_process'; import { join } from 'path'; // 定位 cli.js let cliPath; try { const prefix = execSync('npm config get prefix', { encoding: 'utf-8' }).trim(); cliPath = join(prefix, 'node_modules', '@anthropic-ai', 'claude-code', 'cli.js'); readFileSync(cliPath); } catch { const home = process.env.USERPROFILE || process.env.HOME; const candidates = [ // Windows (npm global) join(home, 'AppData', 'Roaming', 'npm', 'node_modules', '@anthropic-ai', 'claude-code', 'cli.js'), // Linux / WSL (npm global) '/usr/lib/node_modules/@anthropic-ai/claude-code/cli.js', '/usr/local/lib/node_modules/@anthropic-ai/claude-code/cli.js', ]; cliPath = null; for (const p of candidates) { try { readFileSync(p); cliPath = p; break; } catch { continue; } } } if (!cliPath) { console.error('❌ 找不到 Claude Code cli.js,请确认已全局安装 @anthropic-ai/claude-code'); process.exit(1); } console.log(`📂 cli.js: ${cliPath}`); const patches = [ { name: 'Windows', original: 'windows:["clip"]', patched: 'windows:["chcp 65001 >nul & clip"]' }, { name: 'WSL', original: 'wsl:["clip.exe"]', patched: `wsl:["cmd.exe /c 'chcp 65001 >nul & clip'"]` }, ]; let content = readFileSync(cliPath, 'utf-8'); let changed = false; for (const p of patches) { if (content.includes(p.patched)) { console.log(`✅ ${p.name} 补丁已存在`); } else if (content.includes(p.original)) { content = content.replace(p.original, p.patched); changed = true; console.log(`🔧 ${p.name} 补丁已应用: ${p.original} → ${p.patched}`); } else { console.warn(`⚠️ ${p.name} 未找到原始字符串,可能 cli.js 结构已变更`); } } if (changed) { writeFileSync(cliPath, content, 'utf-8'); console.log('\n✅ 补丁完成!重启 Claude Code 即可生效'); } else { console.log('\n✅ 无需修改'); } console.log('\n💡 提示: 每次 Claude Code 更新后需重新运行此脚本');


方案二:clip.cmd 包装器 + PATH 拦截

创建一个 clip.cmd 包装器,通过 PATH 优先级让系统先找到它而不是原始的 clip.exe

优点: 不修改 cli.js,Claude Code 更新后无需重新操作
缺点: 需要修改 PATH 环境变量,该 pwsh 会话内所有调用 clip 的程序都会走包装器(实际影响极小,因为几乎没有其他程序通过命令行调用 clip.exe

注意: 此方案仅适用于 Windows 原生环境,不适用于 WSL。WSL 用户请使用方案一。

使用方法

第一步:创建包装器

在你的用户目录下创建 ~/clip-fix/clip.cmd(路径可自定义),内容如下:

@echo off chcp 65001 >nul C:\Windows\System32\clip.exe

第二步:修改 PowerShell/BASH 配置

编辑你的 PowerShell 配置文件($PROFILE),在末尾添加:

# Fix: Claude Code /copy 中文乱码补丁 $env:PATH = "$HOME\clip-fix;$env:PATH"

感谢佬友的补充,

【2026-3-10官方已修复该问题,此贴终结】尝试解决 ClaudeCode在Windows环境下/copy乱码问题 开发调优
git-bash启动的cc得这样 .bashrc export PATH="$HOME/clip-fix:$PATH"

第三步:重启 PowerShell 并启动 Claude Code

新开一个 pwsh 窗口即可生效。

原理说明

原本 PATH 搜索顺序: ... → C:\Windows\System32\clip.exe ← 系统原版(不支持 UTF-8) 修改后: ... → ~\clip-fix\clip.cmd ← 包装器(先被找到,切换代码页后再调用真正的 clip.exe) ... → C:\Windows\System32\clip.exe ← 不会被执行到


关于 utf8clip

感谢哈雷酱推荐了 bluemarsh/utf8clip 这个项目。它的思路是对的——用 .NET 以 UTF-8 读取 stdin,再通过 Windows API 写入剪贴板,和我们的修复方向一致。

但它不能直接用于解决这个问题,原因是:

  • 命令名不同: utf8clip 安装后的命令是 utf8clip,而 Claude Code 硬编码调用的是 clip。即使装了 utf8clip,Claude Code 依然会调用系统的 clip.exe,根本不会走到 utf8clip,如果要替换仍然需要做一个包装器或改名——又回到了 PATH 拦截的套路
  • 额外依赖: 需要 .NET Core 3.0+ 运行时
网友解答:
--【壹】--:

我自己电脑也是alias了一个魔改的,但是要发出来还是要考虑最用户使用环境的最小侵入


--【贰】--:

git-bash启动的cc得这样

.bashrc

export PATH="$HOME/clip-fix:$PATH"


--【叁】--:

用鼠标选择文字后自动复制乱码,如果选择完,按Ctrl+C复制,再粘贴就不乱码了


--【肆】--:

我是在Teminal用的,鼠标选文字不会自动复制,感谢佬友提供这个情况,这也太离谱了


--【伍】--:

image595×271 16.3 KB

没有命令 我 cc 版本是 2.1.63 CC 插件也是 2.1.63

image352×176 30.2 KB


--【陆】--:

2.1.59 增加的


--【柒】--:

感谢回复


--【捌】--: phaseddd:

命令名不同: utf8clip 安装后的命令是 utf8clip,而 Claude Code 硬编码调用的是 clip。即使装了 utf8clip,Claude Code 依然会调用系统的 clip.exe,根本不会走到 utf8clip,如果要替换仍然需要做一个包装器或改名——又回到了 PATH 拦截的套路

.bashrc
alias clip="utf8clip"

phaseddd:

需要 .NET Core 3.0+ 运行时

我直接丢到 Claude.ai 上让他给我拉 utf8clip 仓库 转写成 rust

而且正则patch匹配那个容易吃瘪 还是AST解析匹配好些 我群里不是发的有模板来着


--【玖】--:

好吧, 我不用 cli 已经好几个月了


--【拾】--:

image1257×660 68.7 KB
/copy和直接从回复里面手动复制都会


--【拾壹】--:

嗯 ?还有回归问题?


--【拾贰】--:

这两者是完全不同的TUI模式

加这个或者不加的话

操作能力也不一样

我们都是不加的那种旧式的


--【拾叁】--:

感谢佬友补充,已更新主贴


--【拾肆】--:

我也碰到了,而且直接复制内容去粘贴也会乱码,我放假看看


--【拾伍】--:

今天更新2.1.91后,又出现了乱码问题 呜呼


--【拾陆】--: 哈雷彗星:

AST 解析匹配

触及到俺知识盲区了,我晚上再去磨一磨


--【拾柒】--:

CLAUDE_CODE_NO_FLICKER=1
我是加上这个配置后,再复制或者/export都乱码,去掉就不乱码


--【拾捌】--:

当然只有cli有


--【拾玖】--:

我都没理解, 有 /copy 这个命令吗 我的CC 怎么没提示

这是自定义命令吗 还是自身的命令?

问题描述:
起因

本来只是个小bug,不影响使用,但是最近写文档还挺多的,这个功能对我比较实用

问题描述

Claude Code 的 /copy 命令在 Windows(包括 WSL)上复制含中文、日文、韩文、越南语等非 ASCII 字符的文本时,粘贴结果为乱码(mojibake)。macOS 和 Linux 用户不受此问题影响。

相关 Issue: #22346(OPEN, stale)、#27709(closed as duplicate)

测试环境: Windows 10/11, Claude Code v2.1.x, pwsh 7


为什么会产生这个问题?

Claude Code 在不同平台使用不同的剪贴板命令(cli.js 中定义):

{ macos: ["pbcopy"], // ✅ 原生支持 UTF-8 linux: ["xclip -selection clipboard", "wl-copy"], // ✅ 原生支持 UTF-8 wsl: ["clip.exe"], // ❌ 不支持 UTF-8 windows: ["clip"], // ❌ 不支持 UTF-8 }

当用户执行 /copy 时,执行链路如下:

用户在 pwsh 中运行 claude (Node.js 进程) │ ├─ /copy 触发剪贴板写入 │ ├─ Node.js 调用 execa("clip", { input: text, shell: true }) │ │ │ ├─ Node.js 内部将 JavaScript 字符串 (UTF-16) 转为 UTF-8 字节流 │ │ 写入子进程的 stdin │ │ │ └─ shell: true → 使用 process.env.comSpec (= cmd.exe) │ │ │ └─ 实际执行: cmd.exe /d /s /c "clip" │ │ │ └─ clip.exe 从 stdin 读取字节流 │ │ │ └─ ❌ clip.exe 使用系统 OEM 代码页 (如 CP437/CP936) │ 解读字节流,而非 UTF-8 │ └─ 结果:UTF-8 字节被按错误编码解读 → 乱码

核心矛盾:

环节 编码
Node.js stdin 输出 UTF-8
clip.exe stdin 读取 系统 OEM 代码页(GetOEMCP(),通常为 CP437 或 CP936)

这个编码不匹配是乱码的直接原因。

为什么不能通过 ~/.bashrc$PROFILE 修复?

我们测试了以下方案,均无法解决此问题:

~/.bashrc 中设置 chcp 65001

.bashrc 只在 Claude Code 的 Bash Tool(执行 shell 命令的工具)调用时被 source。而 /copy 是 Node.js 进程直接 spawn cmd.exe 子进程,完全不经过 bash:

/copy 的路径:Node.js → cmd.exe → clip.exe (不经过 bash) Bash Tool: Node.js → bash (source .bashrc) (跟 /copy 无关)

在 PowerShell $PROFILE 中设置 chcp 65001

chcp 65001 改变的是当前 console 会话的代码页,但 clip.exe 读取 stdin 时使用的是系统 OEM 代码页(通过 GetOEMCP() 获取),这是系统级全局设置,chcp 无法改变它。

那为什么 chcp 65001 >nul & clip 在同一个 cmd 会话里就能工作?

因为 chcp 65001 在同一个 cmd.exe 会话中同时改变了该进程的 stdin 处理方式。clip.exe 作为同一会话的下一个命令直接执行时,继承了这个修改。但从外部(pwsh、bash)设置的 codepage 无法传递到 Node.js 随后 spawn 的 cmd.exe 进程中。

PowerShell $input | Set-Clipboard

PowerShell 的 $input 自动变量从 stdin 读取时,同样不使用 UTF-8 编码,即使在 pwsh 7 中也是如此。经 Node.js 模拟测试验证,结果仍为乱码。


解决方案

以下提供两种修复方案,任选其一即可。

方案一:补丁脚本(推荐)

直接修改 cli.js 中的剪贴板命令,在调用 clip 前先用 chcp 65001 切换到 UTF-8 代码页。

优点: 最精准,只改一个字符串,零副作用,不影响系统中任何其他软件
缺点: 每次 Claude Code 更新后需重新执行

使用方法

  1. 将下方脚本保存为 fix-claude-copy.mjs
  2. 执行补丁:

node fix-claude-copy.mjs

  1. 重启 Claude Code 即可生效

补丁内容

脚本会自动定位 cli.js 并做以下替换:

# Windows windows:["clip"] → windows:["chcp 65001 >nul & clip"] # WSL wsl:["clip.exe"] → wsl:["cmd.exe /c 'chcp 65001 >nul & clip'"]

完整脚本代码

#!/usr/bin/env node /** * Claude Code /copy 中文乱码修复补丁 * * 问题: Windows/WSL 上 /copy 命令使用 clip.exe,不支持 UTF-8 stdin,导致中文乱码 * 修复: 在调用 clip 之前先用 chcp 65001 切换到 UTF-8 代码页 * * 用法: node fix-claude-copy.mjs * 每次 Claude Code 更新后需重新执行 */ import { readFileSync, writeFileSync } from 'fs'; import { execSync } from 'child_process'; import { join } from 'path'; // 定位 cli.js let cliPath; try { const prefix = execSync('npm config get prefix', { encoding: 'utf-8' }).trim(); cliPath = join(prefix, 'node_modules', '@anthropic-ai', 'claude-code', 'cli.js'); readFileSync(cliPath); } catch { const home = process.env.USERPROFILE || process.env.HOME; const candidates = [ // Windows (npm global) join(home, 'AppData', 'Roaming', 'npm', 'node_modules', '@anthropic-ai', 'claude-code', 'cli.js'), // Linux / WSL (npm global) '/usr/lib/node_modules/@anthropic-ai/claude-code/cli.js', '/usr/local/lib/node_modules/@anthropic-ai/claude-code/cli.js', ]; cliPath = null; for (const p of candidates) { try { readFileSync(p); cliPath = p; break; } catch { continue; } } } if (!cliPath) { console.error('❌ 找不到 Claude Code cli.js,请确认已全局安装 @anthropic-ai/claude-code'); process.exit(1); } console.log(`📂 cli.js: ${cliPath}`); const patches = [ { name: 'Windows', original: 'windows:["clip"]', patched: 'windows:["chcp 65001 >nul & clip"]' }, { name: 'WSL', original: 'wsl:["clip.exe"]', patched: `wsl:["cmd.exe /c 'chcp 65001 >nul & clip'"]` }, ]; let content = readFileSync(cliPath, 'utf-8'); let changed = false; for (const p of patches) { if (content.includes(p.patched)) { console.log(`✅ ${p.name} 补丁已存在`); } else if (content.includes(p.original)) { content = content.replace(p.original, p.patched); changed = true; console.log(`🔧 ${p.name} 补丁已应用: ${p.original} → ${p.patched}`); } else { console.warn(`⚠️ ${p.name} 未找到原始字符串,可能 cli.js 结构已变更`); } } if (changed) { writeFileSync(cliPath, content, 'utf-8'); console.log('\n✅ 补丁完成!重启 Claude Code 即可生效'); } else { console.log('\n✅ 无需修改'); } console.log('\n💡 提示: 每次 Claude Code 更新后需重新运行此脚本');


方案二:clip.cmd 包装器 + PATH 拦截

创建一个 clip.cmd 包装器,通过 PATH 优先级让系统先找到它而不是原始的 clip.exe

优点: 不修改 cli.js,Claude Code 更新后无需重新操作
缺点: 需要修改 PATH 环境变量,该 pwsh 会话内所有调用 clip 的程序都会走包装器(实际影响极小,因为几乎没有其他程序通过命令行调用 clip.exe

注意: 此方案仅适用于 Windows 原生环境,不适用于 WSL。WSL 用户请使用方案一。

使用方法

第一步:创建包装器

在你的用户目录下创建 ~/clip-fix/clip.cmd(路径可自定义),内容如下:

@echo off chcp 65001 >nul C:\Windows\System32\clip.exe

第二步:修改 PowerShell/BASH 配置

编辑你的 PowerShell 配置文件($PROFILE),在末尾添加:

# Fix: Claude Code /copy 中文乱码补丁 $env:PATH = "$HOME\clip-fix;$env:PATH"

感谢佬友的补充,

【2026-3-10官方已修复该问题,此贴终结】尝试解决 ClaudeCode在Windows环境下/copy乱码问题 开发调优
git-bash启动的cc得这样 .bashrc export PATH="$HOME/clip-fix:$PATH"

第三步:重启 PowerShell 并启动 Claude Code

新开一个 pwsh 窗口即可生效。

原理说明

原本 PATH 搜索顺序: ... → C:\Windows\System32\clip.exe ← 系统原版(不支持 UTF-8) 修改后: ... → ~\clip-fix\clip.cmd ← 包装器(先被找到,切换代码页后再调用真正的 clip.exe) ... → C:\Windows\System32\clip.exe ← 不会被执行到


关于 utf8clip

感谢哈雷酱推荐了 bluemarsh/utf8clip 这个项目。它的思路是对的——用 .NET 以 UTF-8 读取 stdin,再通过 Windows API 写入剪贴板,和我们的修复方向一致。

但它不能直接用于解决这个问题,原因是:

  • 命令名不同: utf8clip 安装后的命令是 utf8clip,而 Claude Code 硬编码调用的是 clip。即使装了 utf8clip,Claude Code 依然会调用系统的 clip.exe,根本不会走到 utf8clip,如果要替换仍然需要做一个包装器或改名——又回到了 PATH 拦截的套路
  • 额外依赖: 需要 .NET Core 3.0+ 运行时
网友解答:
--【壹】--:

我自己电脑也是alias了一个魔改的,但是要发出来还是要考虑最用户使用环境的最小侵入


--【贰】--:

git-bash启动的cc得这样

.bashrc

export PATH="$HOME/clip-fix:$PATH"


--【叁】--:

用鼠标选择文字后自动复制乱码,如果选择完,按Ctrl+C复制,再粘贴就不乱码了


--【肆】--:

我是在Teminal用的,鼠标选文字不会自动复制,感谢佬友提供这个情况,这也太离谱了


--【伍】--:

image595×271 16.3 KB

没有命令 我 cc 版本是 2.1.63 CC 插件也是 2.1.63

image352×176 30.2 KB


--【陆】--:

2.1.59 增加的


--【柒】--:

感谢回复


--【捌】--: phaseddd:

命令名不同: utf8clip 安装后的命令是 utf8clip,而 Claude Code 硬编码调用的是 clip。即使装了 utf8clip,Claude Code 依然会调用系统的 clip.exe,根本不会走到 utf8clip,如果要替换仍然需要做一个包装器或改名——又回到了 PATH 拦截的套路

.bashrc
alias clip="utf8clip"

phaseddd:

需要 .NET Core 3.0+ 运行时

我直接丢到 Claude.ai 上让他给我拉 utf8clip 仓库 转写成 rust

而且正则patch匹配那个容易吃瘪 还是AST解析匹配好些 我群里不是发的有模板来着


--【玖】--:

好吧, 我不用 cli 已经好几个月了


--【拾】--:

image1257×660 68.7 KB
/copy和直接从回复里面手动复制都会


--【拾壹】--:

嗯 ?还有回归问题?


--【拾贰】--:

这两者是完全不同的TUI模式

加这个或者不加的话

操作能力也不一样

我们都是不加的那种旧式的


--【拾叁】--:

感谢佬友补充,已更新主贴


--【拾肆】--:

我也碰到了,而且直接复制内容去粘贴也会乱码,我放假看看


--【拾伍】--:

今天更新2.1.91后,又出现了乱码问题 呜呼


--【拾陆】--: 哈雷彗星:

AST 解析匹配

触及到俺知识盲区了,我晚上再去磨一磨


--【拾柒】--:

CLAUDE_CODE_NO_FLICKER=1
我是加上这个配置后,再复制或者/export都乱码,去掉就不乱码


--【拾捌】--:

当然只有cli有


--【拾玖】--:

我都没理解, 有 /copy 这个命令吗 我的CC 怎么没提示

这是自定义命令吗 还是自身的命令?