[Bug Report]:Windows 上 dsh plugin 的含空格路径参数会被拆断 #1420
Replies: 3 comments 1 reply
|
Windows 含空格路径被拆断——命令行参数解析的经典问题(未加引号/未转义空格)。 排查:dsh plugin 命令的路径参数加引号("C:/path with space/..."),或检查调用方是否做了转义。Windows 安装/路径坑见第 3 章 + 第 12 章:https://github.com/Electricitysheep/dsh-handbook/blob/main/docs/03-profiles.md |
|
分析完全正确——我把你的三点根因对着 master 源码逐一核实,全部成立,而且仓库自己的脚本早就记录了这个坑。补充几个关键事实 + 修复方向设计。 核实结果
修复方向(供维护者参考)方案 A(最小改动): function quoteForCmd(argument: string): string {
// cmd.exe 引号规则:含空白/元字符才加引号,内部 " 翻倍
return /[\s&|<>^()%!"]/.test(argument)
? `"${argument.replace(/"/g, '""')}"`
: argument
}
// spawnSync('pnpm', args.map(anchorPathSpec).map(quoteForCmd), { shell: true })注意 方案 B(npm 同款,更可控):不用 shell:true,直接 建议:修复放 给用户的临时 workaround在修复合入前,Open Design 这类调用方可以先把路径改成无空格副本(如 需要的话我可以把方案 A 的补丁(含单测)整理成完整草案贴上来,等上游开放 PR 通道直接用。 |
|
你说得对,我之前的排查方向偏了——调用方引号没问题是表象,根子在 修复方向同意: |
Uh oh!
There was an error while loading. Please reload this page.
[Bug Report]:Windows 上
dsh plugin的含空格路径参数会被拆断我在用 Open Design 桌面版(把 DeepSeek Harness 作为设计引擎)时报错:它自动安装连接组件
@open-design/dsh-runtime失败,报DeepSeek Harness could not install the Open Design connection component.。查下来根因在 dsh ,所以提交这个 bug。1. 环境
复现不需要 Open Design,本地任意一个含空格的包路径就能触发。
2. 复现步骤
Open Design 的场景等价于这条命令,它的连接组件默认路径带空格:
3. 实际行为 vs 期望行为
安装失败,每次必现。路径在空格处被拆成两段传给 pnpm。前半段(
...\Programs\Open)被 pnpm 当成一个不存在的路径规格,报 ENOENT;后半段(Design\resources\...\x.tgz)变成多余参数,按相对路径从 profile 目录解析。实际报错:Open Design 安装器对用户显示的是:
期望 pnpm 把完整路径当一个参数收下,安装成功。
4. 根因
apps/cli/src/plugin.ts的runPlugin(源码)在 Windows 上用shell: true转发 pnpm,参数不转义:拆开看有三个细节:
anchorPathSpec只重写相对路径(.、..、file:、link:),绝对路径原样透传,它自己的注释就写着 "Absolute specs ... pass through untouched"。shell: true把命令和参数用空格拼成一行交给 cmd.exe,不做转义。Node 22 起对这个用法打 DEP0190 弃用警告。scripts/verify-node-next-types.ts的注释写 "shell:true, which space-joins args UNESCAPED (DEP0190) — a hazard",那里改用execFileSync(process.execPath, [...])绕开了,runPlugin没跟上。我在本机验证过:
spawnSync(node, ['-e', …, 'C:/…/Open Design/…/x.tgz'], { shell: true }),cmd 在空格处就把参数拆了,报'C:\Program' is not recognized。5. 影响范围
触发条件是 Windows、本地路径规格(tarball、目录或
file:)、路径带空格,三个凑齐必现。从 registry 装包(dsh plugin add @scope/pkg)不受影响,包名没空格;macOS 和 Linux 上shell是 false,也不受影响。受害的集成有 Open Design 桌面版,它自动装连接组件时路径在
%LOCALAPPDATA%\Programs\Open Design\...,必然撞上。严重性算中等:报错清晰、不损坏数据,但确定性强,报错内容也不会让人联想到空格问题,还挡住了一个真实的三方集成。建议 P2。
6. 临时规避
先把 tarball 复制到无空格路径再 add:
7. 修复方向
两个办法:
.cmd背后的pnpm.cjs),用spawnSync(process.execPath, [pnpmJs, ...args], { shell: false })启动。参数数组语义由 Node 保证,不经 shell 拼接,这也是verify-node-next-types.ts已经在用的办法。推荐这个。shell: true,但对每个参数做 cmd 引号转义。能修,顺带消掉 DEP0190 警告。8. 备注
行号和源码链接基于 master 当前代码(
apps/cli/src/plugin.ts、scripts/verify-node-next-types.ts)。Open Design 只是发现场景,最小复现见 §2,不依赖它。All reactions