原因分析
根本原因:MS-DOS 保留设备名
NUL 是 Windows 从 1981 年 MS-DOS 1.0 继承下来的保留设备名(Reserved Device Name)。DOS 时代为硬件设备预留了特殊文件名,这些名称在文件系统中具有特殊含义:
| 名称 | 含义 |
|---|---|
CON |
控制台(键盘/屏幕) |
NUL |
空设备(写入即丢弃) |
PRN |
打印机 |
AUX |
辅助设备 |
COM1 ~ COM9 |
串行端口 |
LPT1 ~ LPT9 |
并行端口 |
这些名称不区分大小写 ,且即使加扩展名也无效 (如 nul.txt 同样被保留)。
为什么能创建却删不掉?
Windows 的底层文件系统(NTFS)本身支持 这些文件名,但 Win32 API 层会拦截并拒绝操作。这就造成了一个尴尬局面:
- 资源管理器可以显示这些文件(因为 NTFS 允许存在)
- 但无法删除它们(因为 Win32 API 拒绝)
常见产生场景
nul 文件通常由以下情况产生:
- 跨平台 shell 混淆 :在 Git Bash / MSYS2 中执行
> nul重定向时,Bash 不认识NUL是 Windows 空设备,而是将其当作普通文件名创建 - AI 编程工具 :Claude Code 等工具在 Windows 上频繁产生
nul文件,有用户一次会话发现 1290 个NUL文件 - 跨系统传输:从 Linux/macOS 解压的压缩包
- 恶意软件:利用此特性制造"无法删除"的文件
解决办法
不要使用
shift+delete删除,删完后退出该文件夹依旧会被还原
方案一:UNC 路径前缀
在路径前加 \\?\ 前缀,绕过 Win32 API 的路径解析限制:
CMD 命令提示符(管理员):
cmd
del "\\?\C:\完整路径\nul"
PowerShell(管理员):
powershell
Remove-Item -LiteralPath "\\?\C:\完整路径\nul" -Force
方案二:WSL 方式
如果你安装了 WSL,Linux 内核不识别 DOS 保留名,可直接删除:
bash
rm "/mnt/c/完整路径/nul"
或批量清理整个项目:
bash
find /mnt/c/项目路径 -name "nul" -type f -delete
方案三:Git Bash 方式
- 打开包含不可删除的文件目录
- 在空白处,右击,选择Git Bash Here
- 在窗口内输入
rm nul即可