那是对的吗?如果“是”,是否有支持此声明的技术文档?
这有点真实,但根本不是.我的意思是什么?首先,让我们解决您的文档问题.以下内容来自PowerShell version 3.0 Language Specification第3.13段:
If a command writes a single object, its successor receives that
object and then terminates after writing its own object(s) to its
successor. If, however, a command writes multiple objects, they are
delivered one at a time to the successor command, which executes once
per object. This behavior is called streaming. In stream processing,
objects are written along the pipeline as soon as they become
available, not when the entire collection has been produced.When processing a collection, a command can be written such that it
can do special processing before the initial element and after the
final element.
现在,让我们简要了解一下cmdlet的组成.
Cmdlet及其构建块
将cmdlet视为另一个函数,每次调用时要同步执行的一组连续语句可能很诱人.然而,这是不正确的.
PowerShell中的cmdlet是一个实现至少3种方法之一的对象:
> BeginProcessing() – 当管道开始执行时运行一次
> ProcessRecord() – 为收到的每个管道项目运行
> EndProcessing() – 在处理完最后一个管道项后运行一次
管道开始执行后,将在管道中的每个cmdlet上调用BeginProcessing().从这个意义上说,管道中的所有cmdlet都是“并行”运行的 – 但是这种设计基本上允许我们用单个线程执行管道 – 因此不需要按照设计执行管道的涉及多个线程的实际并行处理.
可能更准确地指出cmdlet在管道中并发执行.
我们来试试吧!
由于上述三种方法直接映射到我们可以在高级函数中定义的begin,process和end块,因此很容易看到此执行流程的效果.
让我们尝试将10个对象提供给由三个cmdlet组成的管道,并使用Write-Host报告它们的状态,看看会发生什么(请参阅下面的代码):
PS C:\> 1..10 |first |second |third |Out-Null
请注意,PowerShell通过-OutBuffer通用参数支持外部输出缓冲控制,这也会影响执行流程:
希望这有一定道理!
这是我为上面的演示编写的代码.
以下函数的Write-Host输出将根据我们使用的别名更改其颜色,因此在shell中更容易区分.
function Test-Pipeline { param( [Parameter(ValueFromPipeline)] [psobject[]]$InputObject ) begin { $WHSplat = @{ ForegroundColor = switch($MyInvocation.InvocationName){ 'first' { 'Green' } 'second' { 'Yellow' } 'third' { 'Red' } } } Write-Host "Begin $($MyInvocation.InvocationName)" @WHSplat $ObjectCount = 0 } process { foreach($Object in $InputObject) { $ObjectCount += 1 Write-Host "Processing object #$($ObjectCount) in $($MyInvocation.InvocationName)" @WHSplat Write-Output $Object } } end { Write-Host "End $($MyInvocation.InvocationName)" @WHSplat } } Set-Alias -Name first -Value Test-Pipeline Set-Alias -Name second -Value Test-Pipeline Set-Alias -Name third -Value Test-Pipeline