Windows 下 Bash 工具全部失败(exit 127):spawn 链路破坏命令行引号
Nobody has claimed this yet.
- Dominant language
- No language data
- Stars
- 22
- Forks
- 1
- PR merge metrics
- No merged PRs in 30d
Description
提交前确认 · Pre-submission checklist
- 我已搜索过现有 issue,确认这不是重复 / I searched existing issues and confirmed this isn't a duplicate.
- 我已阅读 CONTRIBUTING.md / I've read CONTRIBUTING.md.
问题类别 · Category
其他 / 不确定 · Other / Not sure
涉及的 Agent 框架 · Agent framework
ZCode Agent(自研)
严重程度 · Severity
阻塞使用 · Blocking (无法使用核心功能 / core function unusable)
复现频率 · Reproducibility
必现 · Always
问题描述 · Description
ZCode Bug 报告:Windows 下 Bash 工具全部失败(exit 127)— spawn 链路破坏命令行引号
- 版本:ZCode 3.10.2,build 35824adf,Windows 10 (19045) x64,安装在某个盘符下的自定义目录(非 Program Files)
- Shell:Git Bash(MINGW64,MSYS runtime 2.11.2)
- 关键环境:Windows 用户目录含中文(下文以
C:\Users\<中文用户名>指代) - 复现:100% 复现,跨两天两个会话;ZCode 之外执行同样操作全部正常
症状
每次 Bash 工具调用报:
Exit code 127
/usr/bin/bash: line 4: . '/c/Users/<中文用户名>/.zcode/cli/exec/bash-startup/<会话ID>/embedded-search-startup-<内容哈希>.sh'
exit "": No such file or directory
ZCode 每次调用生成的 wrapper 脚本,其第 4 行强制 source 的启动脚本(grep/rg 包装函数,文件确认存在且可读)打不开 → 退出码 127 → 用户命令从未被执行(日志实测:一条 sleep 8 的调用总耗时仅 796 毫秒)。
根因:spawn 链路破坏 -c payload 中的引号
最小对照(同一时刻、同一测试脚本文件,文件确认存在可读):
payload(经 bash -c 传入) |
结果 |
|---|---|
echo DQ_"AB"_END(引号紧贴单词) |
❌ 输出 DQ_"AB"_END,引号变成了字面字符 |
echo "SP=[$*] N=[$#]"(引号完整包住含空格的词) |
✅ 正常展开 |
. /d/测试目录/测试脚本.sh(无引号) |
✅ RC=0 |
. "/d/测试目录/测试脚本.sh"(引号紧贴) |
❌ 报“文件不存在”,且报错里引号成了文件名的一部分 |
| 同一脚本经 stdin 送入 | ✅ RC=0 |
特征:紧贴单词的引号被字面化(疑似被二次转义后未还原),完整包词的引号部分存活——像是命令行在某层被重新分词并错误重组。子进程的 BASH_COMMAND 显示首条命令文本完好,但含紧贴引号的命令执行语义已变。
ZCode 内外对照(排除机器与安全软件因素)
在 ZCode 之外经 cmd 批处理执行(cmd → bash -c → bash -c 三层嵌套):
| 测试 | 结果 |
|---|---|
| 纯 ASCII 路径的 payload,含嵌套 spawn、单引号 | ✅ 全部成功 |
| payload 含用户主目录展开后的中文路径(反斜杠形式) | ❌ 整条命令被当成一个文件名(参数在中文与反斜杠处被拆散)— 独立的第二个问题 |
→ 机器本身与安全软件(火绒,进程监控驱动活跃状态下测试)无责;病灶位于 ZCode 的 Node → CreateProcessW → msys bash 这条 spawn 链路。
已排除的因素
- WSL bash 抢占 PATH(uname 实测为 MINGW64)
- locale/编码问题(全链路 UTF-8 正常)
- 文件缺失或权限问题(stat/head 实测可读)
dangerouslyDisableSandbox开关(开启后依旧)- 用户自定义 hooks(禁用并重启后依旧)
- ZCode 版本过旧(已升级到最新)
- 进程启动时序竞态(延迟 2 秒后仍失败)
- 环境变量注入(已完整导出检查:PS4/PS1 正常,无 BASH_ENV、NODE_OPTIONS、MSYS2_ARG_CONV_EXCL 等可疑项)
给开发的排查建议
- 最小复现入口:ZCode 会话内执行任意
bash -c 'echo DQ_"AB"_END'(注意引号紧贴单词); - 检查 Node 的 child_process 在 Windows 上构建命令行 → msys-2.dll 重建 argv 的往返过程:重点排查
"是否被双重转义后未还原; - 中文用户目录出现在命令行时参数拆分异常(见对照表第二个问题),怀疑与非 ASCII 命令行处理相关;
- 影响面:ZCode 的 bash wrapper(强制 source 启动脚本、
exit "$变量"、echo "<用户命令>"预览行)全部依赖引号语义,因此 Bash 工具 100% 不可用;连带用户 PreToolUse 钩子(node.exe 收到含中文的脚本路径参数)每次执行失败。
复现步骤 · Steps to reproduce
- Windows 用户目录为中文的环境下,打开 ZCode(3.10.2,build 35824adf),任意会话中让 Agent 执行任意 Bash 命令(如
echo hi) - 观察:Bash 调用 100% 报 Exit code 127:
/usr/bin/bash: line 4: . '/c/Users/<中文用户名>/.zcode/cli/exec/bash-startup/<会话ID>/embedded-search-startup-<哈希>.sh'
exit "": No such file or directory - 用户命令从未被执行:日志实测一条
sleep 8的调用总耗时仅 796ms - 最小复现(会话内让 Agent 执行):bash -c 'echo DQ_"AB"END'
→ 输出 DQ"AB"_END,引号变成字面字符;而去掉引号的同命令正常 - 对照:同样命令在 ZCode 之外的 Git Bash / cmd 批处理(含三层嵌套 spawn)全部正常;
同一脚本经 stdin 送入 bash 也正常;文件本身存在且可读(stat/head 实测)
期望表现 · Expected behavior
Bash 工具正常执行用户命令;wrapper 中 source 启动脚本成功;带引号的 -c payload
引号语义保持不变(与 ZCode 之外的 Git Bash 行为一致)。
实际表现 · Actual behavior
所有 Bash 调用 100% 报 Exit 127,报错见复现步骤;根因是 spawn 链路把 -c payload 中
紧贴单词的引号字面化(疑似双重转义未还原),导致 source 目标被改写成不存在的文件。
ZCode 版本 · ZCode version
v3.10.2
设备 / 系统 / 浏览器 · Device / OS / Browser
PC 笔记本 / Windows 10 专业版 19045 x64 / ZCode 桌面版(Git Bash MINGW64,MSYS runtime 2.11.2),不涉及浏览器
截图 / 录屏 / 日志 · Screenshots / Recordings / Logs
失败报错(每次 Bash 调用 100% 复现):
Exit code 127
/usr/bin/bash: line 4: . '/c/Users/<中文用户名>/.zcode/cli/exec/bash-startup/<会话ID>/embedded-search-startup-<哈希>.sh'
exit "": No such file or directory
日志佐证(zcode-*.jsonl):一条 sleep 8 的 Bash 调用,tool.call.started → tool.call.completed
总耗时仅 796ms —— 用户命令从未被执行。
最小对照(同一时刻、同一测试脚本):
- bash -c '. /d/测试目录/测试脚本.sh'(无引号) → RC=0,正常
- bash -c '. "/d/测试目录/测试脚本.sh"'(引号紧贴) → 失败,引号成了文件名的一部分
- 同一脚本经 stdin 送入 bash → RC=0,正常
- ZCode 之外 cmd→bash→bash 三层嵌套、带引号 payload → 全部正常(机器与安全软件无责)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the Bash tool's Node child_process spawn path and reproduce bash -c 'echo DQ_"AB"_END' on Windows with Git Bash. Trace how the command line passes through CreateProcessW and the MSYS runtime, including a Chinese user path. Done means quoted -c payloads and wrapper startup scripts execute correctly, while the reported comparison cases remain valid.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- bash, node.js
- Domain
- cli, operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100