电源外壳 |获取子项通过管道运行,不提供所有项



由于 Azure Dev Ops 在部署时将 LF 转换为 CRLF,我必须创建一个自定义函数,该函数将搜索.sh文件并将其转换回它们在存储库 (LF( 中的存储方式。那段代码我做得很好,但我真的很想做一个很棒的函数,我可以做一个 get-childitem 递归来查找.sh文件,然后将其管道传输到我的自定义函数,将它们变回正确的格式。

我的问题是我、孩子和功能不是不相处。

为了保持对主要问题的关注,这里有一个过于简单的示例函数:

Function List-Items {
param (
[Parameter(ValueFromPipeline = $true)]$items
)
Write-Output "Item Count: $($items | Measure-Object | select -ExpandProperty Count)"
foreach ($item in $items) {
Write-Output "Item: $($item)"
}
}

我用以下方法称呼它:

dir c:temp | List-Items

然而,即使通过此命令显然有 52 个项目:dir c:temp | Measure-Object

该函数只能看到这 52 条记录的最后一条记录。如何访问自定义列表项函数中的所有 52 个?

这是预期行为。实际上,PowerShell 中的高级功能有三个不同的块:

  • begin- 在管道开始执行之前运行一次
  • process-对每个管道绑定的输入项运行一次
  • end- 在上游 cmdlet 发送完输入运行一次

当您不指定任何这些不同的块,而只有一个函数体时,例如:

Function List-Items {
param (
[Parameter(ValueFromPipeline = $true)]$items
)
# Do stuff with $items
}

它实际上相当于:

Function List-Items {
param (
[Parameter(ValueFromPipeline = $true)]$items
)
end {
# Do stuff with $items
}
}

换句话说,函数体默认充当end块,这就是为什么您只看到绑定到$items的最后一个值。

要解决此问题,请显式指定process块:

Function List-Items {
param (
[Parameter(ValueFromPipeline = $true)]$items
)
process {
foreach ($item in $items) {
Write-Output "Item: $($item)"
}
}
}

您需要一个进程块,该进程块针对每个管道项目运行一次。

function hi { 
param([Parameter(ValueFromPipeline=$True)]$inputvalue)
process { 
$inputvalue.count 
} 
}
1,2,3 | hi
1
1
1

最新更新