Вопрос или проблема
Я только что открыл новую Powershell.
where.exe находит то, что я ищу. Where-Object не находит. Почему?
PS C:\Users\dpchi> where wget.exe
PS C:\Users\dpchi> where.exe wget.exe
C:\ProgramData\chocolatey\bin\wget.exe
PS C:\Users\dpchi> where.exe where.exe
C:\Windows\System32\where.exe
PS C:\Users\dpchi> where-object where.exe
PS C:\Users\dpchi> (get-host).version
Major Minor Build Revision
----- ----- ----- --------
7 4 6 -1
Что здесь происходит?
Ответ или решение
Вопрос, который вы подняли, касается различий между командами where.exe
и Where-Object
в PowerShell. Чтобы прояснить ситуацию, давайте подробно рассмотрим, что происходит и почему вы видите такое поведение.
Причина проблемы
1. Разные предназначения команд:
where.exe
— это отдельный исполняемый файл (утилита), который находится в вашей системе, и его основная функция — находить файлы по заданному имени в путях, указанных в переменной окруженияPATH
.Where-Object
— это встроенная команда в PowerShell, которая предназначена для фильтрации объектов по заданному критерию. Она принимает объекты, переданные через конвейер, и позволяет отбирать из них нужные. Однако у нее нет механизма для поиска файлов в файловой системе или переменной средыPATH
.
2. Когда вы вызываете Where-Object
с аргументом where.exe
:
- PowerShell пытается использовать
Where-Object
для фильтрации объектов, но без предоставления соответствующего контекста или данных этот вызов не имеет смысла. Он не знает, что искать, и, следовательно, не возвращает ничего.
Подробности вызовов
В вашем примере:
where wget.exe
вы не получаете результатов, потому что PowerShell ищет файл непосредственно через Where-Object
, а не через утилиту where.exe
, которая специально предназначена для этой задачи.
Сравните это с вызовом:
where.exe wget.exe
Этот вызов успешно находит файл, так как where.exe
действительно осуществляет поиск по путям, заданным в переменной PATH
.
Проверка версии PowerShell
Поскольку вы используете PowerShell версии 7.4.6, важно отметить, что эта версия полностью совместима с where.exe
и использует PowerShell Core. Тем не менее, это не влияет на поведение команд, так как в данном случае проблема заключается в отсутствии понимания назначения команд.
Как решить вашу задачу
Если ваша цель состоит в том, чтобы использовать функциональность, аналогичную where.exe
, вам следует использовать его напрямую. Если же вы хотите фильтровать объекты в PowerShell, то вам нужно передать их в Where-Object
. Пример:
$files = Get-ChildItem -Path C:\ -Recurse
$files | Where-Object { $_.Name -eq "wget.exe" }
Этот код ищет все файлы в корневом каталоге C:\
и подкаталогах и фильтрует только те, имя которых равно "wget.exe".
Заключение
Таким образом, основная причина, по которой Where-Object
не находит ваши исполняемые файлы, заключается в том, что его предназначение не является поиском файлов в системе. Для поиска исполняемых файлов используйте where.exe
, а для фильтрации объектов в PowerShell используйте Where-Object
. Понимание назначения и контекста команд поможет вам более эффективно использовать PowerShell.