为何Get-ChildItem -Recurse仅在指定低层级目录时才能找到目标文件?
我来帮你梳理这个问题的可能原因,先看你给出的测试场景:
当你从C盘根目录执行这条递归搜索命令时:
Get-ChildItem -Path c:\ -Recurse -Filter sshd_config
成功找到了三个sshd_config文件,分布在Git和不同版本Visual Studio的嵌套目录中:
Directory: C:\Program Files\Git\etc\ssh Mode LastWriteTime Length Name ---- ------------- ------ ---- -a--- 21/12/2022 14:18 3115 sshd_config Directory: C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\Git\etc\ssh Mode LastWriteTime Length Name ---- ------------- ------ ---- -a--- 09/06/2024 10:10 3116 sshd_config Directory: C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\Git\etc\ssh Mode LastWriteTime Length Name ---- ------------- ------ ---- -a--- 17/02/2024 14:33 3116 sshd_config
但你提到如果换从某个低层级目录开始搜索,反而能找到目标文件(你后续内容没写完,我基于这类问题的常见情况分析),通常出现这种差异的原因有以下几种:
1. 权限限制
C盘根目录下存在大量系统级目录(比如Windows目录、部分Program Files子目录),普通用户权限下无法访问这些目录。当你从根目录递归搜索时,Get-ChildItem会直接跳过无权限访问的目录,导致可能漏掉藏在这些目录里的目标文件;而如果直接从有权限的低层级目录开始搜索,就能完整遍历该目录下的所有子目录,自然能找到文件。
验证/解决办法:以管理员身份启动PowerShell,再执行根目录的递归搜索,对比结果是否有变化。
2. 路径长度超出限制
Windows传统的路径长度限制是260字符,当递归搜索到路径超长的目录时,Get-ChildItem会报错并跳过这些路径。而低层级目录的基础路径较短,不容易触发这个限制,所以能正常找到文件。
验证/解决办法:
- 执行命令时查看错误信息,确认是否有路径过长的提示:
Get-ChildItem -Path c:\ -Recurse -Filter sshd_config -ErrorAction SilentlyContinue -ErrorVariable searchErrors $searchErrors - 启用Windows长路径支持(需要管理员权限):
修改后重启PowerShell生效,就能支持最长32767字符的路径。Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem' -Name 'LongPathsEnabled' -Value 1
3. 搜索过程被中断
从C盘根目录递归搜索需要遍历大量文件和目录,过程中如果遇到系统资源占用过高、磁盘错误等情况,可能会导致搜索提前中断,从而漏掉部分结果;而低层级目录的搜索范围小,完成速度快,不容易出现中断。
验证办法:观察搜索过程的耗时和状态,是否有异常终止的情况,也可以尝试分批搜索根目录下的子目录(比如先搜C:\Program Files,再搜C:\Users等),看是否能找到遗漏的文件。
备注:内容来源于stack exchange,提问作者evo_race

