在 Windows 10 cmd.exe 下,该命令del *.tmp可能会静默删除project.tmpl.
是否有一些选项、解决方法、注册表项或仪式牺牲可以防止这种情况发生?
令人难以置信的是:在我的机器上,C: 驱动器在 2020 年由 Windows 10 安装程序格式化:
(其中法语错误消息表示未找到文件)。
phu*_*clv 36
一个文件可能有短的 DOS 8.3 名称,并且出于兼容性原因1,DOS 时代的所有内部命令也可以同时使用长名称和短名称1,因此可能会意外匹配具有长扩展名的文件。类似的问题还有很多:
最好使用 PowerShell,因为不再匹配短名称。dir在 cmd 中必须匹配短名称,以免破坏旧程序。PowerShell 没有这个限制。只需运行Remove-Item *.tmp或其任何别名,例如rm *.tmp,del *.tmp
在 cmd 中,您必须findstr像这样进行过滤
for /F "delims=" %f in ('dir /B ^| findstr /I /E ".tmp"') do @del "%f"
Run Code Online (Sandbox Code Playgroud)
(在批处理文件中替换%f为%%f)
还有许多其他解决方案,例如forfiles(因为这不是 cmd 的内部命令),您可以在如何获取“dir”和“copy”命令以对“*.xyz”而不是“*.xyz~”进行操作中找到“?
但是,禁用 8.3 名称生成并删除所有短名称会更好。事实上,由于性能原因,Windows 8 和 Windows Server 2012新格式化的卷将默认禁用 8.3 名称生成。这也有助于避免这样的情况:WinXP dir command: 3 和 4 char extensions are the same?
事实上,当您格式化新数据卷时,最新版本的 Windows Server 甚至不启用 8.3 命名。
如果您的驱动器仍然启用了 8.3 名称生成,则运行以下命令在驱动器 C 上禁用它:
fsutil 8dot3name set C: 1
Run Code Online (Sandbox Code Playgroud)
或运行 fsutil 8dot3name set 1以在所有卷上禁用它
该设置也可以在注册表中设置。对应的键是HKLM\System\CurrentControlSet\Control\FileSystem\NtfsDisable8dot3NameCreation。fsutil和注册表项的值是这样的
如果名称在那里,它也可以删除 fsutil 8dot3name strip
请注意,fsutil必须以管理员权限运行
1旧命令使用FindFirstFile匹配长名称和短名称的旧API列出其文件。请参阅为什么会FindFirstFile找到短名称?. 应该使用新代码FindFirstFileEx来避免这种情况
发生这种情况的原因是 Windows 保留了与来自MS-DOS 的文件名的兼容性,其中文件名仅限于 3 个字符的扩展名。为了便于过渡,Windows 95的推出,每一个文件都有一个“8.3”的别名,也被称为文件的“短名”兼容模式:除project.tmpl,同一文件也可访问PROJEC~1.TMP。您可以在目录列表中看到这些短名称dir /x。通配符模式*.tmp匹配这个替代名称(文件名不区分大小写)。Microsoft 将其记录在案dir;它也适用于其他命令,包括del.
我可以重现您在我的公司 Windows 10 机器上观察到的行为(不是从以前的 Windows 10 升级的)。我有本地管理员权限,但没有域管理员权限,而且我不能运行fsutil 8dot3name query c:( Error: Access is denied.)。
如果您控制生成临时文件的系统部分,一个可靠的解决方法是给它们一个不超过 3(或 0)个字符长的扩展名。*.tm或者*.temp不会匹配具有不同扩展名的 8.3 文件名别名。或者,将这些临时文件放在单独的目录中,并在要删除它们时删除整个目录。
除了phuclv 的回答中提供的基于 CMD 的解决方案之外,您还可以使用 not-well-known-but-very-cool FORFILES命令:
FORFILES /M *.tmp /C "CMD /C ECHO @path && DEL @path"
Run Code Online (Sandbox Code Playgroud)
“搜索掩码”参数 ( /M) 与 8.3 名称不匹配,因此.tmp和.tmpl是两个不同的扩展名,没有任何额外的过滤。搜索掩码也不区分大小写。
例如:
C:\TEMP>echo a > del_test_1.tmp
C:\TEMP>echo a > del_test_2.TMP
C:\TEMP>echo a > del_test_3.tmpl
C:\TEMP>dir *.tmp
Volume in drive C is Windows
Volume Serial Number is B0F0-812B
Directory of C:\TEMP
04/28/2021 11:46 AM 4 del_test_1.tmp
04/28/2021 11:48 AM 4 del_test_2.TMP
04/28/2021 11:48 AM 4 del_test_3.tmpl
3 File(s) 12 bytes
0 Dir(s) 179,312,234,496 bytes free
C:\TEMP>FORFILES /M *.tmp /C "CMD /C ECHO @path && DEL @path"
"C:\TEMP\del_test_1.tmp"
"C:\TEMP\del_test_2.TMP"
C:\TEMP>dir *.tmp
Volume in drive C is Windows
Volume Serial Number is B0F0-812B
Directory of C:\TEMP
04/28/2021 11:48 AM 4 del_test_3.tmpl
1 File(s) 4 bytes
0 Dir(s) 179,310,305,280 bytes free
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3766 次 |
| 最近记录: |