PowerShell:Get-Item 与 Get-ChildItem 的输出类型

3
我试图按名称字母顺序打印出环境变量,最初想到的方法是:
Get-Item env: | Sort-Object -Property Name

但输出始终是未排序的。然后我尝试了以下方法:

Get-ChildItem env: | Sort-Object -Property Name

获得了预期的、正确排序的输出. 这表明,尽管来自Get-Item env:Get-ChildItem env:的(格式化的)输出看起来完全相同(即字典),但其输出类型并不相同。
将命令的输出传输到| Get-TypeData中,发现Get-Item env:似乎实际上只返回单个System.Collections.DictionaryEntry,而Get-ChildItem env:返回多个System.Collections.DictionaryEntry对象。
有人可以解释一下这里具体发生了什么吗?为什么两种看似不同的输入数据类型会产生相同的输出/字符串表示形式?PowerShell是否对Get-Item输出中的单个条目字典对象做了一些隐式的“拆箱”操作?
在Windows 10上使用PowerShell 5.1。
1个回答

3

简而言之:

  • Get-Item 在使用 env: 驱动器的 根目录 时不值得使用;要枚举当前进程的环境变量,请改用 Get-ChildItem env:

  • 通常,使用 Get-Item 获取有关目标项 本身 的信息,使用 Get-ChildItem 获取其 子项 的信息。


Get-Item 旨在返回给定项 本身,而 Get-ChildItem 返回其 子项

注意:对于那些根据定义无法拥有子项的项(例如单个环境变量或文件),Get-ChildItem回退 到该项本身 - 请参见底部部分。

Get-Item env: 类似于 Get-Item C:\,因为您正在请求 PowerShell 驱动器的 根目录 本身,而不是它的子项。

env: 是包含当前进程中定义的所有环境变量的 PowerShell 驱动器,并且 本身 具有有限实用性的表示形式,只有访问其 子项 才能按预期工作。 (与根目录 文件夹(例如 C:\)相比,它本身具有有意义的属性,例如时间戳、权限等。)

env:驱动器返回的PowerShell内容是它用于存储有关单个环境变量信息的字典的条目集合,作为单个对象[1],这是通常行为,因为命令通常预期将集合的元素逐个发送到管道中。有关该项本身的信息实际上也包括子项,这也是不寻常的。

这是一个无关紧要的问题,因为Get-ChildItem env:将以概念上更清晰的方式提供相同的功能,但是您可以使用(...),即分组运算符来强制枚举Get-Item env:输出的集合中的项目:

# Currently the same as: Get-ChildItem env: | Sort-Object Name
(Get-Item env:) | Sort-Object Name

如果PowerShell返回整个字典而不是条目集合,则可以更容易地访问.Keys来获取所有环境变量名称和.Values来获取所有值,这将更加合理。实际上,由于成员访问枚举, 您可以通过访问当前由Get-Item env:返回的条目集合上的.Key和.Value属性来实现相同的效果。注意:字典/散列表不应在PowerShell管道中枚举。
(Get-Item env:).Name  # returns array of all env.-var. *names*; same as .Key 

(Get-Item env:).Value  # returns array of all *values*

“Get-ChildItem” 命令的不规范使用

如上所述,对于那些根据定义不能有子项的项目类型,Get-ChildItem 会退回到 Get-Item 的行为,因此以下两个命令实际上是等效的:

Get-Item env:Path

# Same, because an environment variable can never have children,
# but it's better to use Get-Item.
Get-ChildItem env:Path

然而,在这种情况下,从概念上讲最好使用Get-Item,因为它能明确地表达意图。
另外:常用的$env:PATH语法直接检索给定环境变量的值是命名空间变量表示法的一个实例,相当于Get-Content env:PATH(而不是Get-Item)。

[1] Get-Item env: 返回 PowerShell 用于存储环境变量信息的 System.Collections.Generic.Dictionary`2 实例的 .Values 属性值。该值作为单个对象输出,其类型是嵌套在字典类型中的集合类型,即 System.Collections.Generic.Dictionary`2.ValueCollection;您可以使用 Get-Item env: | Get-Member 检查该类型。


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