3

我试图按字母顺序(按名称)打印出环境变量,我能想到的第一件事是:

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

但是输出总是未排序的。然后我尝试了以下

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

并得到预期的、正确排序的输出。这表明Get-Itemand的输出Get-ChildItem不是同一类型,即使Get-Item env:and的(格式化)输出Get-ChildItem env:看起来完全相同(即字典)

将命令的输出通过管道| Get-TypeData显示,Get-Item env:似乎实际上只返回 single System.Collections.DictionaryEntry,而Get-ChildItem env:返回多个System.Collections.DictionaryEntry对象。

有人可以解释这里到底发生了什么吗?为什么两种看似不同的输入数据类型会产生相同的输出/字符串表示?PowerShell 是否对输出中的单项字典对象进行了一些隐式“拆箱” Get-Item

在 Windows 10 上使用 PowerShell 5.1。

4

1 回答 1

2

tl;博士:

  • Get-Item不值得与env:驱动器的root一起使用;要枚举当前进程的环境变量,请Get-ChildItem env:改用。

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


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

注意:对于根据定义不能有子项的项目(例如单个环境变量或文件),请 Get-ChildItem 回退到项目本身 - 请参阅底部部分。

Get-Item env:类似于Get-Item C:\您要求PowerShell 驱动器本身的,而不是其子驱动器的根。

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

PowerShell 为env:驱动器返回的是字典中的条目集合,它用于将有关各个环境变量的信息存储为单个对象[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获取所有值。(不希望在 PowerShell 管道中枚举字典/哈希表)。

实际上,由于成员枚举,您可以通过访问属性.Key.Value当前返回的条目集合来达到相同的效果Get-Item env:

(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(not Get-Item)。


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

于 2020-01-29T11:30:01.477 回答