jja*_*cek 7 powershell pipeline powershell-3.0 powershell-5.0
使用以下代码,$t等于@(1,2).
$t = "before"
1..2 | Tee-Object -Variable t
Run Code Online (Sandbox Code Playgroud)
那么为什么下一个代码片段$t等于"before"而不是@(1)*?
$t = "before"
1..2 | Tee-Object -Variable t | Select-Object -First 1
Run Code Online (Sandbox Code Playgroud)
我在Powershell版本5和版本3中看到了相同的结果.
这与管道的工作方式有关.如果您使用不同的cmdlet,就像Write-Verbose它将按预期工作:
$t = "before"
1..2 | Tee-Object -Variable t | Write-Verbose -Verbose
Run Code Online (Sandbox Code Playgroud)
考虑到管道中,每个功能或小命令可以使用Begin,Process和End块.
所有Begin块首先运行,然后Process为每个管道对象调用一次,然后调用所有Ends.
变量赋值必须在End块中发生.
从PowerShell v3开始,cmdlet可以中断管道.
这对于某些事情来说非常有用,Select-Object -First 1因为它意味着整个管道可以在第一个对象之后停止,而不是为每个项目执行一次,即使其余部分将被丢弃.
但这也意味着该End块永远不会运行.
如果你在v2中启动PowerShell: powershell.exe -Version 2.0
然后运行第二个示例,它将按预期工作,因为管道无法在该版本中过早停止.
这是一个演示:
function F1 {
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline)]
$o
)
Begin {
Write-Verbose "Begin" -Verbose
}
Process {
Write-Verbose $o -Verbose
$o
}
End {
Write-Verbose "End" -Verbose
}
}
Run Code Online (Sandbox Code Playgroud)
然后叫它:
1..2 | F1
Run Code Online (Sandbox Code Playgroud)
与
1..2 | F1 | Select-Object -First 1
Run Code Online (Sandbox Code Playgroud)
您还可以通过以下方式证明ForEach-Object:
1..2 | ForEach-Object -Begin {
Write-Verbose "Begin" -Verbose
} -Process {
Write-Verbose $_ -Verbose
$_
} -End {
Write-Verbose "End" -Verbose
}
Run Code Online (Sandbox Code Playgroud)
与
1..2 | ForEach-Object -Begin {
Write-Verbose "Begin" -Verbose
} -Process {
Write-Verbose $_ -Verbose
$_
} -End {
Write-Verbose "End" -Verbose
} | Select-Object -First 1
Run Code Online (Sandbox Code Playgroud)
根据您链接的文档,您可以使用该-Wait参数来关闭此优化:
$t = "before"
1..2 | Tee-Object -Variable t | Select-Object -First 1 -Wait
Run Code Online (Sandbox Code Playgroud)
这将填充,$t但可能不会与您想要的价值.它将包含@(1,2),大概是因为-OutVariable被放置Tee-Object而不是放置Select-Object.
请记住,管道的"结果"是从执行中返回的内容(左侧=),并且在所有实例中都是正确的.
-OutVariable是某些cmdlet实现的东西,它很可能必须在该End特定cmdlet 的块中实现,因此预测它将给出的内容高度依赖于理解管道的执行流程.
因此,为了回答您的评论中的问题,我觉得可以正确实施.我误解了你的断言吗?
| 归档时间: |
|
| 查看次数: |
815 次 |
| 最近记录: |