PowerShell: типы вывода Get-Item и Get-ChildItem
Я пытался распечатать переменные среды в алфавитном порядке (по имени), и первое, что я смог придумать, это:
Get-Item env: | Sort-Object -Property Name
Но вывод всегда был несортированным. Затем я попробовал следующее
Get-ChildItem env: | Sort-Object -Property Name
И получил ожидаемый, правильно отсортированный результат. Это говорит о том, что выводGet-Item
а также Get-ChildItem
не одного типа, даже если (отформатированный) вывод из Get-Item env:
а также Get-ChildItem env:
выглядит точно так же (т.е. словарь)
Передача вывода команд в | Get-TypeData
показал, что Get-Item env:
кажется, на самом деле возвращается только один System.Collections.DictionaryEntry
, в то время как Get-ChildItem env:
возвращает несколько System.Collections.DictionaryEntry
объекты.
Может кто-нибудь объяснить, что именно здесь происходит? Почему два, казалось бы, разных типа входных данных создают идентичное внешнее представление вывода / строки? PowerShell неявно "распаковывает" объект словаря с одной записью изGet-Item
выход?
Использование PowerShell 5.1 в Windows 10.
1 ответ
tl;dr:
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:\
, который сам имеет значимые свойства, такие как отметки времени, разрешения и т. д.)
Что 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
(не Get-Item
).
[1] Get-Item env:
возвращает .Values
стоимость собственности System.Collections.Generic.Dictionary`2
экземпляр, который PowerShell использует для хранения информации о переменных среды. Это значение выводится как один объект, и его тип представляет собой тип коллекции, вложенный в тип словаря, System.Collections.Generic.Dictionary`2.ValueCollection
; вы можете проверить тип с помощьюGet-Item env: | Get-Member