Неожиданные результаты Get-ChildItem -recurse

Может ли кто-нибудь объяснить этот вывод при использовании командлета Get-ChildItem для вывода списка файлов в несуществующей папке? Например:

Get-ChildItem -Path "c:\nonexisitantfolder" -recurse

Я предполагал, что он запустится по заданному пути и сразу же потерпит неудачу, поскольку пути не существует. Вместо этого он, кажется, сканирует весь диск (или, по крайней мере, я предполагаю, что это то, что происходит, поскольку он время от времени выводит сообщения об отказе в доступе для несвязанных папок), а затем в конечном итоге терпит неудачу. Это почти то же самое, что когда абсолютный путь не может быть найден - а в мире Windows это определенно абсолютный путь - он начинает искать его как относительный путь к подпапке?

Примечание. Я не пытаюсь составить список файлов в несуществующем каталоге. Я наткнулся на это маловероятное поведение при тестировании того, как сценарий будет реагировать на получение ложного имени каталога в качестве входных данных.

🤔 А знаете ли вы, что...
PowerShell был создан компанией Microsoft в 2006 году и первоначально назывался 'Monad'.


1
50
2

Ответы:

Это ожидаемое поведение: сценарий пытается разрешить несуществующий путь как относительный. Это заставляет PowerShell запускаться из текущего рабочего каталога и рекурсивно искать папку, потенциально сканируя весь диск C, если он не найден в подкаталогах.

Чтобы просканировать только несуществующую папку, используйте командлет Test-Path, чтобы проверить, существует ли она, прежде чем отображать ее содержимое. Если папка не существует, отобразите предупреждающее сообщение. Скрипт позволит избежать ненужного сканирования других каталогов и обеспечит более эффективный подход.


Решено

вр; доктор

Чтобы избежать проблемного поведения, используйте -LiteralPath вместо -Path.

# Fails, if the target path doesn't exist, thanks to `-LiteralPath`
Get-ChildItem -LiteralPath "c:\nonexistentfolder" -Recurse

Параметр -Path Get-ChildItem изначально рассматривает заданный путь как выражение подстановочный знак.
Также обратите внимание, что если вы не укажете -Path явно перед аргументом пути, он подразумевается позиционно.

Неожиданным моментом является то, что в сочетании с -Recurse последний компонент пути, привязанного к -Path, неожиданно ищется на каждом уровне поддерева каталогов родительского пути - даже если этот последний компонент не содержит реальных метасимволов подстановки, таких как * и ?. .

То есть Get-ChildItem -Path "C:\nonexistentfolder" -Recurse ищет файлы и папки с именем nonexistentfolder на каждом уровне поддерева каталогов C:\.

Это проблемное и потенциально деструктивное поведение является предметом проблемы GitHub № 5699.

Напротив, -LiteralPath по замыслу воспринимает свои аргументы буквально и использует их как есть.