【发布时间】:2020-07-02 13:00:00
【问题描述】:
PowerShell Strongly Encouraged Development Guidelines cmdlet 应该是 Implement for the Middle of a Pipeline 但我怀疑这对于 -Last 的参数是不可行的 Select-Object。仅仅是因为您无法预先确定最后一个条目。换句话说:您需要等待输入流完成,直到您定义最后一个条目。
为了证明这一点,我写了一个小脚本:
$Data = 1..5 | ForEach-Object {[pscustomobject]@{Index = "$_"}}
$Data | ForEach-Object { Write-Host 'Before' $_.Index; $_ } |
Select-Object -Last 5 | ForEach-Object { Write-Host 'After' $_.Index }
并将其与Select-Object *进行比较:
$Data | ForEach-Object { Write-Host 'Before' $_.Index; $_ } |
Select-Object * | ForEach-Object { Write-Host 'After' $_.Index }
有结果(右:Select-Object -Last 5,左:Select-Object *):
-Last 5 *
------- -
Before 1 Before 1
Before 2 After 1
Before 3 Before 2
Before 4 After 2
Before 5 Before 3
After 1 After 3
After 2 Before 4
After 3 After 4
After 4 Before 5
After 5 After 5
尽管没有记录,但我认为我可以从中得出结论,-Last 参数确实阻塞了管道。
这没什么大不了的,但我还针对-First 参数对其进行了测试,得到了一些令人不安的结果。为了更好地展示这一点,我没有选择所有对象,而只是选择了 **-First 2**:
$Data | ForEach-Object { Write-Host 'Before' $_.Index; $_ } |
Select-Object -First 2 | ForEach-Object { Write-Host 'After' $_.Index }
Before 1
After 1
Before 2
After 2
请注意,使用 -First 2 参数不仅以下 cmdlet 显示两个对象,而且前面的 cmdlet (ForEach-Object { Write-Host 'Before' $_.Index; $_ }) 也仅显示 2 个对象(而不是 5 个)。
显然,-First 参数直接引用了先前 cmdlet 的对象,这与例如使用 -Last 2 参数:
$Data | ForEach-Object { Write-Host 'Before' $_.Index; $_ } |
Select-Object -Last 2 | ForEach-Object { Write-Host 'After' $_.Index }
Before 1
Before 2
Before 3
Before 4
Before 5
After 4
After 5
使用Out-Host 而不是Write-Host cmdlet 或将结果发送到变量时也会发生这种情况,例如:
$Before = ""; $After = ""
$Data | ForEach-Object { $Before += $_.Index; $_ } | Select-Object -First 2 | ForEach-Object { $After += $_.Index }
$Before
$After
这显示在 Windows Powershell (5.1.18362.628) 和 PowerShell Core (7.0.0) 上。
这是一个错误吗?
【问题讨论】:
-
Sort-Object、Group-Object和Select-Object[带有“全部需要”参数之一] _要求管道阶段发送“不再有项目”之前的前一个做需要的事情。这是合乎逻辑的......我认为它已记录在案,但我目前找不到。 -
"这是一个错误吗?" - what 是一个错误吗?您描述了一些观察到的行为,并且您似乎完全有能力推理为什么,但我没有看到任何东西......坏了?
-
@Mathias,抱歉,不是很清楚,但“-First 2”的问题是前面的 cmdlet 还显示 2 个对象,而不是最初的 5 (我已将此添加到问题中)。
-
@iRon 啊,明白了!有一个很好的解释!
-
Select-object 不会阻塞,但背景中的 format-table 会阻塞。我喜欢 select-object -first 杀死管道的功能。 select-object -last 会阻塞是有道理的。
标签: powershell pipeline select-object