由于 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