zai-org / zai-org/feedback

Windows 下 Bash 工具全部失败(exit 127):spawn 链路破坏命令行引号

Open
#466 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

priority: P2 status: 待评估 type: Bug
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 等可疑项)

给开发的排查建议

  1. 最小复现入口:ZCode 会话内执行任意 bash -c 'echo DQ_"AB"_END'(注意引号紧贴单词);
  2. 检查 Node 的 child_process 在 Windows 上构建命令行 → msys-2.dll 重建 argv 的往返过程:重点排查 " 是否被双重转义后未还原;
  3. 中文用户目录出现在命令行时参数拆分异常(见对照表第二个问题),怀疑与非 ASCII 命令行处理相关;
  4. 影响面:ZCode 的 bash wrapper(强制 source 启动脚本、exit "$变量"echo "<用户命令>" 预览行)全部依赖引号语义,因此 Bash 工具 100% 不可用;连带用户 PreToolUse 钩子(node.exe 收到含中文的脚本路径参数)每次执行失败。
复现步骤 · Steps to reproduce
  1. Windows 用户目录为中文的环境下,打开 ZCode(3.10.2,build 35824adf),任意会话中让 Agent 执行任意 Bash 命令(如 echo hi)
  2. 观察: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
  3. 用户命令从未被执行:日志实测一条 sleep 8 的调用总耗时仅 796ms
  4. 最小复现(会话内让 Agent 执行):bash -c 'echo DQ_"AB"END'
    → 输出 DQ
    "AB"_END,引号变成字面字符;而去掉引号的同命令正常
  5. 对照:同样命令在 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.