管道传递DirectoryInfo对象时的参数绑定不一致问题
PowerShell中
Get-ChildItem参数绑定的不一致问题解析 我平时常用这种简化别名写法,能正常运行:
gci -ad | %{$_ | gci}
但帮论坛用户排查时发现,下面这种写法无法正常工作:
gci -ad | %{$_.Parent | gci}
每次迭代都会抛出错误:
gci : Cannot find path 'C:\Users\keith\Documents\Documents' because it does not exist. At line:1 char:25 + gci -ad | %{$_.Parent | gci} + ~~~ + CategoryInfo : ObjectNotFound: (C:\Users\keith\Documents\Documents:String) [Get-ChildItem], ItemNotFoundException + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
哪怕执行下面的命令,结果全为True:
gci -ad | %{$_.GetType() -eq $_.Parent.GetType()}
我确定这和参数绑定有关,想搞懂这种明显不一致的原因。
问题核心:参数绑定的隐式转换差异
虽然$_(当前目录对象)和$_.Parent(父目录对象)都是System.IO.DirectoryInfo类型,但管道传递给gci时的参数绑定逻辑存在关键区别:
- 传递
$_时,PowerShell会直接将DirectoryInfo对象绑定到Get-ChildItem的-LiteralPath参数,基于对象本身的完整路径执行遍历,所以能正常工作。 - 传递
$_.Parent时,PowerShell会触发隐式字符串转换——DirectoryInfo对象的默认字符串表示是它的Name属性值(仅目录名,不含完整路径)。此时gci会把这个目录名当作当前工作目录的子路径去查找,就出现了C:\Users\keith\Documents\Documents这种重复路径,自然找不到对应的目录。
修复方法
要让$_.Parent正常传递给gci,有两种常用方式:
- 明确指定参数,强制绑定到
-LiteralPath:gci -ad | %{ gci -LiteralPath $_.Parent } - 先通过
Get-Item包装,确保PowerShell识别为路径对象:gci -ad | %{ $_.Parent | Get-Item | gci }
内容的提问来源于stack exchange,提问作者Keith Miller
相关产品推荐
相关产品推荐

