有子目录为什么"get-childItem -recurse | select-string foo"不报错?
Why does "get-childItem -recurse | select-string foo" not result in an error if there are subdirectories?
尝试在目录上使用 select-string
导致错误:
PS C:\> select-string pattern P:\ath\to\directory
select-string : The file P:\ath\to\directory cannot be read: Access to the path 'P:\ath\to\directory' is denied.
但是,当我使用 get-childItem -recurse
时,命令完成时没有问题:
PS C:\> get-childItem -recurse P:\ath\to | select-string pattern
这让我感到惊讶,因为 get-childItem recurse
还会将目录传递到管道中。因此,我假设 select-string
在处理第一个目录时会引发相同的错误。
既然不是这样,我想知道目录在管道中的位置或如何被过滤掉。
Select-String
的 -Path
参数需要文件路径:
-Path
Specifies the path to the files to search. Wildcards are permitted. The default location is the local directory.
Specify files in the directory, such as log1.txt, *.doc, or .. If you specify only a directory, the command fails.
这就是当您将目录路径传递给 -Path
参数时出现错误的原因。
当您将对象通过管道传输到 Select-String
时,它们不一定需要可以映射到 Select-String
的 -Path
的 Path
属性:
You can pipe any object that has a ToString method to Select-String
.
因此您还可以将原始字符串通过管道传输到 Select-String
:
'test' | Select-String -Pattern 'test'
这一行将 return test
.
Get-ChildItem
returns System.IO.FileInfo
或 System.IO.DirectoryInfo
类型的对象。 Select-String
将使用 System.IO.FileInfo
的 Path
属性来解析文件的内容,并将使用 System.IO.DirectoryInfo
的字符串表示来准确解析此字符串表示(路径本身).这就是为什么您不会在管道中出现错误。
New-Item -Name 'test' -Type Directory | Select-String -Pattern 'test'
这一行将return指向刚刚创建的目录的路径test
。
TL;DR: 物体魔法。
当Get-Childitem
为运行时,它将return一个对象集合。这将传递给 Select-String
。该 cmdlet 的 source 在 Github 上可用。有一个 ProcessRecord()
方法可以处理输入对象。它包含一些对象类型检查以及这些是否是目录。像这样,
if (_inputObject.BaseObject is FileInfo fileInfo)
...
if (expandedPathsMaybeDirectory && Directory.Exists(filename))
...
因此,Get-Child
的集合包含 DirectoryInfo
和 FileInfo
对象并不重要;该 cmdlet 足够聪明,可以弄清楚它正在尝试使用什么。
尝试在目录上使用 select-string
导致错误:
PS C:\> select-string pattern P:\ath\to\directory
select-string : The file P:\ath\to\directory cannot be read: Access to the path 'P:\ath\to\directory' is denied.
但是,当我使用 get-childItem -recurse
时,命令完成时没有问题:
PS C:\> get-childItem -recurse P:\ath\to | select-string pattern
这让我感到惊讶,因为 get-childItem recurse
还会将目录传递到管道中。因此,我假设 select-string
在处理第一个目录时会引发相同的错误。
既然不是这样,我想知道目录在管道中的位置或如何被过滤掉。
Select-String
的 -Path
参数需要文件路径:
-Path
Specifies the path to the files to search. Wildcards are permitted. The default location is the local directory.
Specify files in the directory, such as log1.txt, *.doc, or .. If you specify only a directory, the command fails.
这就是当您将目录路径传递给 -Path
参数时出现错误的原因。
当您将对象通过管道传输到 Select-String
时,它们不一定需要可以映射到 Select-String
的 -Path
的 Path
属性:
You can pipe any object that has a ToString method to
Select-String
.
因此您还可以将原始字符串通过管道传输到 Select-String
:
'test' | Select-String -Pattern 'test'
这一行将 return test
.
Get-ChildItem
returns System.IO.FileInfo
或 System.IO.DirectoryInfo
类型的对象。 Select-String
将使用 System.IO.FileInfo
的 Path
属性来解析文件的内容,并将使用 System.IO.DirectoryInfo
的字符串表示来准确解析此字符串表示(路径本身).这就是为什么您不会在管道中出现错误。
New-Item -Name 'test' -Type Directory | Select-String -Pattern 'test'
这一行将return指向刚刚创建的目录的路径test
。
TL;DR: 物体魔法。
当Get-Childitem
为运行时,它将return一个对象集合。这将传递给 Select-String
。该 cmdlet 的 source 在 Github 上可用。有一个 ProcessRecord()
方法可以处理输入对象。它包含一些对象类型检查以及这些是否是目录。像这样,
if (_inputObject.BaseObject is FileInfo fileInfo)
...
if (expandedPathsMaybeDirectory && Directory.Exists(filename))
...
因此,Get-Child
的集合包含 DirectoryInfo
和 FileInfo
对象并不重要;该 cmdlet 足够聪明,可以弄清楚它正在尝试使用什么。