删不掉的 nul:AI 编程助手在 Windows 上的一次跨平台口误
用 AI 编程助手(Claude Code、ZCode 这类 agent)在 Windows 上干活的人,迟早会在某个项目根目录捡到一个幽灵:一个 0 字节的文件,名字叫 nul。git status 里躺着个 ?? nul,资源管理器里看得见,右键删除却报"找不到该项目"。看得见,删不掉,标准的幽灵文件。 它不是病毒,不是 bug,是 AI 助手的一句跨平台口误。 口误发生在哪一句 AI 助手在 Windows 上跑命令,走的通常是 Git Bash——一个 POSIX 语义的 shell。而模型执行命令时有个职业习惯:把无关的日志和报错重定向丢弃,保持输出干净。丢弃输出的写法在两个世界长得不一样: Windows cmd: some.exe >nul (nul 是设备,输出进了黑洞) Bash: some.exe >/dev/null (/dev/null 是设备,输出进了黑洞) 模型识别到宿主是 Windows,出于好意切了 cmd 方言,写下 >nul。但实际执行这句的 shell 是 Git Bash。在 Bash 眼里,nul 不是设备,就是一个普通的文件名——重定向的目标文件不存在时 Bash 会怎么办?创建它。于是磁盘上多了这么个东西。 一句字面级别的口误:语法是 cmd 的,解释器是 Bash 的。两边单独看都没错,拼在一起就生成了一个不属于任何一方意图的文件。 为什么看得见、删不掉 nul 是 DOS 时代的设备保留名,同一家族还有 con、prn、aux、com1 到 com9、lpt1 到 lpt9。Windows 的 Win32 层在解析路径时,会把出现在文件名位置上的这些名字别名到设备对象上。所以资源管理器、del nul、以及一切走 Win32 路径的程序,操作这个名字时碰到的其实是设备,不是文件——“找不到该项目"就是这么来的:它找的确实不是那个文件。 ...