Get-ChildItem 和不间断 space
Get-ChildItem and non-breaking space
在我的文件服务器上工作时,我注意到一个奇怪的文件夹破坏了我的脚本。文件夹名称仅包含一个字符,ascii 值为 160 (non-breaking space, NBSP)。从视觉上看,该名称与 space 字符相同。
简而言之,我在这个文件夹上执行了 Get-ChildItem
,它正在进入无限循环。命令实际上是针对父文件夹执行的,它 returns 又是有问题的文件夹,所以我的脚本进入了无限循环。
您可以轻松地在您自己的环境中进行模拟。在 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
. . .
我在服务器和客户端 OS 上使用 PowerShell 4 和 5 对其进行了测试,其行为相同。命令 Get-Item
也有此名称的问题,并且开关 -Path
和 -LiteralPath
的行为方式相同。我也试过 [System.IO.Directory]
class,但它有同样的问题。
问题: 我已经更新了我的脚本以将具有此名称的文件夹报告为错误并跳过它,但我想知道是否有更聪明的方法来做到这一点?我的目标是 运行 Get-ChildItem
或等同于此类文件夹。
这是一个已知问题吗?如果得到更多人的确认,是否值得在某个地方将其作为错误报告?
如评论中所述,您发现了一个实际错误,希望很快得到修复。
但是,有一个非常可接受的解决方法,您可以在继续使用 Get-ChildItem 的同时轻松应用,而无需排除您的文件夹。
Unicode 版本的 Get-ChildItem 没有这个问题。
(在 Windows 10 环境的 Powershell 5.1 上测试)
要使用它,只需替换
Get-ChildItem -Path 'c:\__tmp' -recurse
来自
Get-ChildItem -LiteralPath '\?\c:\__tmp' -recurse
补充说明
如果需要处理UNC,UNC unicode调用略有不同。
Get-ChildItem -LiteralPath '\?\UNC7.0.0.1\c$\__tmp' -recurse
请注意,为了使其正常工作,我使用 -LiteralPath
参数而不是 -Path
。
参考资料
来自 Microsoft 文档
-LiteralPath
指定一个或多个位置的路径。与 -Path 参数不同,-LiteralPath 参数的值完全按照键入的方式使用。没有字符被解释为通配符。如果路径包含转义字符,请将其括在单引号中。单引号告诉 Windows PowerShell 不要将任何字符解释为转义序列。
关于 unicode 前缀约定:Naming Files, Paths, and Namespaces
奖金
unicode 调用还有解决 260 个字符路径长度限制的好处:
在我的文件服务器上工作时,我注意到一个奇怪的文件夹破坏了我的脚本。文件夹名称仅包含一个字符,ascii 值为 160 (non-breaking space, NBSP)。从视觉上看,该名称与 space 字符相同。
简而言之,我在这个文件夹上执行了 Get-ChildItem
,它正在进入无限循环。命令实际上是针对父文件夹执行的,它 returns 又是有问题的文件夹,所以我的脚本进入了无限循环。
您可以轻松地在您自己的环境中进行模拟。在 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
. . .
我在服务器和客户端 OS 上使用 PowerShell 4 和 5 对其进行了测试,其行为相同。命令 Get-Item
也有此名称的问题,并且开关 -Path
和 -LiteralPath
的行为方式相同。我也试过 [System.IO.Directory]
class,但它有同样的问题。
问题: 我已经更新了我的脚本以将具有此名称的文件夹报告为错误并跳过它,但我想知道是否有更聪明的方法来做到这一点?我的目标是 运行 Get-ChildItem
或等同于此类文件夹。
这是一个已知问题吗?如果得到更多人的确认,是否值得在某个地方将其作为错误报告?
如评论中所述,您发现了一个实际错误,希望很快得到修复。
但是,有一个非常可接受的解决方法,您可以在继续使用 Get-ChildItem 的同时轻松应用,而无需排除您的文件夹。
Unicode 版本的 Get-ChildItem 没有这个问题。 (在 Windows 10 环境的 Powershell 5.1 上测试) 要使用它,只需替换
Get-ChildItem -Path 'c:\__tmp' -recurse
来自
Get-ChildItem -LiteralPath '\?\c:\__tmp' -recurse
补充说明
如果需要处理UNC,UNC unicode调用略有不同。
Get-ChildItem -LiteralPath '\?\UNC7.0.0.1\c$\__tmp' -recurse
请注意,为了使其正常工作,我使用 -LiteralPath
参数而不是 -Path
。
参考资料
来自 Microsoft 文档
-LiteralPath
指定一个或多个位置的路径。与 -Path 参数不同,-LiteralPath 参数的值完全按照键入的方式使用。没有字符被解释为通配符。如果路径包含转义字符,请将其括在单引号中。单引号告诉 Windows PowerShell 不要将任何字符解释为转义序列。
关于 unicode 前缀约定:Naming Files, Paths, and Namespaces
奖金
unicode 调用还有解决 260 个字符路径长度限制的好处: