gpt4 book ai didi

powershell - Powershell 中的管道

转载 作者:行者123 更新时间:2023-12-05 09:04:46 27 4
gpt4 key购买 nike

我在 about_Pipelines 阅读了有关 PowerShell 中的管道工作原理的信息,并了解到管道一次传送一个对象。

所以,这个

Get-Service | Format-Table -Property Name, DependentServices

与此不同

Format-Table -InputObject (Get-Service) -Property Name, DependentServices

所以在这里,根据解释,在第一种情况下,Format-Table 一次作用于一个对象,在第二个示例中,Format-Table适用于一系列对象。如果我错了,请纠正我。

如果是这种情况,那么我想知道 Sort-Object 和其他需要处理数据集合的 cmdlet 如何使用管道字符。

当我这样做时:

Get-Service | Sort-Object

如果 Sort-Object 一次只能处理一个对象,它如何能够进行排序。因此,假设有 100 个服务对象要传递给 Sort-ObjectSort-Object 会被调用 100 次(每次针对一个对象)吗?而且,这将如何产生我在屏幕上看到的排序结果。

最佳答案

Sort-Object(以及其他需要在输出任何内容之前评估所有 输入对象的 cmdlet)的工作方式是一个接一个地收集输入对象,然后不执行任何操作实际工作,直到上游 cmdlet(在本例中为 Get-Service)完成发送输入。

这是如何运作的?好吧,让我们尝试使用 PowerShell 函数重新创建 Sort-Object

为此,我们首先需要了解一个 cmdlet 由 3 个独立的例程组成:

  • Begin - 管道中每个 cmdlet 的 Begin 例程在任何其他事情发生之前被调用一次
  • Process - 此例程在每个 cmdlet 上调用,每次从上游命令接收到输入
  • End - 一旦上游命令调用了 End 并且没有更多的输入项供 Process 处理

(这些是 PowerShell 函数 定义中使用的 block 标签名称 - 在二进制 cmdlet 中,您将覆盖 BeginProcessingProcessRecordEndProcessing cmdlet 方法的实现)

因此,为了“收集”每个输入项,我们需要在命令的 Process block 中添加一些逻辑,然后我们可以将对所有项进行操作的代码放在 结束 block :

function Sort-ObjectCustom
{
param(
[Parameter(Mandatory, ValueFromPipeline)]
[object[]]$InputObject
)

begin {
# Let's use the `begin` block to create a list that'll hold all the input items
$list = [System.Collections.Generic.List[object]]::new()

Write-Verbose "Begin was called"
}

process {
# Here we simply collect all input to our list
$list.AddRange($InputObject)

Write-Verbose "Process was called [InputObject: $InputObject]"
}

end {
# The `end` block is only ever called _after_ we've collected all input
# Now we can safely sort it
$list.Sort()

Write-Verbose "End was called"

# and output the results
return $list
}
}

如果我们使用 -Verbose 调用我们的新命令,我们将看到如何一一收集输入:

PS ~> 10..1 |Sort-ObjectCustom -Verbose
VERBOSE: Begin was called
VERBOSE: Process was called [InputObject: 10]
VERBOSE: Process was called [InputObject: 9]
VERBOSE: Process was called [InputObject: 8]
VERBOSE: Process was called [InputObject: 7]
VERBOSE: Process was called [InputObject: 6]
VERBOSE: Process was called [InputObject: 5]
VERBOSE: Process was called [InputObject: 4]
VERBOSE: Process was called [InputObject: 3]
VERBOSE: Process was called [InputObject: 2]
VERBOSE: Process was called [InputObject: 1]
VERBOSE: End was called
1
2
3
4
5
6
7
8
9
10

有关如何为二进制 cmdlet 实现管道输入处理例程的更多信息,请参阅 "How to Override Input Processing" .

有关如何在函数中利用相同管道语义的更多信息,请参阅 about_Functions_Advanced_Methods and related help topics

关于powershell - Powershell 中的管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68243578/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com