管道和 $_ 在 PowerShell 中如何工作?

Vin*_* Pn 2 powershell

  1. Get-Process|Get-Member $_,为什么这不起作用?如果$_代表管道中的当前对象,上面的输出不应该返回每个进程对象的成员吗?
  2. cmdlet 是否会立即将其所有输出对象通过管道传送到下一个 cmdlet,或者在有可用对象时传送?
  3. 由于#1 不起作用,我$_什么时候可以使用变量?创建此变量的条件将更有帮助,而不仅仅是一个 cmdlet 示例来演示$_.

Mar*_*agg 5

$_ 是一个自动变量,可在某些 cmdlet 的脚本块输入中使用,以表示管道中的当前项目。

Get-Process | Get-Member $_不能因为你送管道对象Get-Member通过|,但你再没有任何方式来访问的内部Get-Member

你可以这样做:

Get-Process | ForEach-Object {
    $_ | Get-Member
}
Run Code Online (Sandbox Code Playgroud)

然后,您将获得由Get-Member输出的对象集合中的每个项目的输出Get-Process,尽管这将是多余的,因为每个项目都是相同的。

Cmdlet 会一次一个地将对象发送到管道中。你可以看到这个例子:

Get-Process | ForEach-Object {
   $_
   Start-Sleep 1
}
Run Code Online (Sandbox Code Playgroud)

通过增加的延迟,您可以看到结果ForEach-Object一旦可用就会一次到达一个。

您可以使用该$_变量的其他地方是Where-ObjectSelect-Object。例如:

Get-Process | Where-Object { $_.name -like 'win*' }
Run Code Online (Sandbox Code Playgroud)

此处Where-Objectcmdlet 获取管道的每个项目,我们使用它$_来访问该项目的 name 属性以查看它是否与 string 类似win。如果是,则它会继续发送(因此会输出到控制台),如果不是,则Where-Object丢弃它。

您可以在进行计算属性时使用$_in Select-Object。例如:

Get-Process | Select-Object name,@{N='WorkingSetGB';E={$_.WorkingSet / 1GB}}
Run Code Online (Sandbox Code Playgroud)

这里我们使用$_来获取WorkingSet每个项目的属性,然后使用 将其转换为 GB 值/ 1GB