Get-ChildItem和不间断空格

33

在处理我的文件服务器时,我注意到一个奇怪的文件夹破坏了我的脚本。这个文件夹的名称只有一个字符,其ASCII值为160(表示不间断空格,NBSP)。从视觉上看,它的名称与空格字符相同。

简而言之,我执行Get-ChildItem命令时,会进入无限循环。实际上,该命令是针对父文件夹执行的,并且再次返回有问题的文件夹,因此我的脚本陷入了无限循环中。

您可以在自己的环境中轻松模拟此情况。在C:\temp文件夹中创建一个名称仅由NBSP组成的新文件夹。您可以通过按住Alt并在数字键盘上按下0160来输入。创建后,请运行

Get-ChildItem C:\Temp\ -Recurse

你将得到无数没有名称的文件夹列表,尽管我只有那一个文件夹。

d-----        6/15/2017   2:20 PM
d-----        6/15/2017   2:20 PM
d-----        6/15/2017   2:20 PM
d-----        6/15/2017   2:20 PM
d-----        6/15/2017   2:20 PM
. . .

我在PowerShell 4和5上进行了测试,包括服务器和客户端操作系统,结果行为相同。命令Get-Item在处理该名称时也存在问题,-Path-LiteralPath开关表现出相同的行为方式。我还尝试使用[System.IO.Directory]类,但它也遇到了相同的问题。

问题:我已更新脚本以将具有此名称的文件夹报告为错误并跳过,但我想知道是否有更聪明的方法?我的目标是对这样的文件夹运行Get-ChildItem或等效命令。

这是一个已知问题吗?如果有更多人确认,是否值得将其报告为错误?


6
没错,我也看到了。肯定是一个错误。对我来说 DirectoryInfo 是有效的:([IO.DirectoryInfo]'c:\temp').EnumerateFileSystemInfos('*', 'AllDirectories') - wOxxOm
1
而且,是的,好老的DIR /S也可以正常工作(在PoSh控制台中不行,因为它只是gci的别名)。 - Igor
1
从堆栈上发生的递归来看,我认为这在任何 .Net 语言中都可以重现。 - Lieven Keersmaekers
5
@LievenKeersmaekers是正确的。这不是PowerShell的问题,而是dotnet的问题。我已经在那里发布了一个问题。 https://github.com/dotnet/corefx/issues/21096 - Igor
1
我会将你的解决方法发布为答案,并提交一个错误报告。这肯定不是该 cmdlet 的预期行为。 - PSGuy
显示剩余10条评论
1个回答

3

正如评论中所提到的,您发现了一个实际错误,希望很快能够被修复。

但是,有一个非常可接受的解决方法,您可以在继续使用Get-ChildItem而无需排除您的文件夹的情况下应用最小的努力。

Get-ChildItem的Unicode版本不会遇到这个问题。(在Windows 10环境上测试了Powershell 5.1) 要使用它,只需替换

Get-ChildItem  -Path 'c:\__tmp' -recurse 

Get-ChildItem  -LiteralPath '\\?\c:\__tmp' -recurse 

附加说明

如果您需要处理UNC路径,UNC Unicode调用略有不同。

Get-ChildItem  -LiteralPath '\\?\UNC\127.0.0.1\c$\__tmp' -recurse 

请注意,为了使此功能正常工作,我使用了-LiteralPath参数而不是-Path参数。
参考资料
来自Microsoft文档 -LiteralPath 指定一个或多个位置的路径。与-Path参数不同,-LiteralPath参数的值完全按照其输入方式使用。没有任何字符被解释为通配符。如果路径包括转义字符,请将其置于单引号中。单引号告诉Windows PowerShell不要将任何字符解释为转义序列。 source 关于unicode前缀约定:Naming Files, Paths, and Namespaces 奖励 Unicode调用还有解决260个字符路径长度限制的好处:在这里查看

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接