我想创建一个枚举一些数据的PowerShell函数,并在所有实例中触发一个脚本块.
到现在为止(这不是实际的代码,但它说明了我的问题):
function Invoke-TenTimes
{
[CmdletBinding()]
param
(
[Parameter(Mandatory=$true, Position=0)]
[ScriptBlock]$Action
)
process
{
$digits = 0..10
$digits | % {
$Action.Invoke($_);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我把这个功能放在我的模块中.但是,当我打电话时,我没有得到任何结果:
Invoke-TenTimes { $_ }
Run Code Online (Sandbox Code Playgroud)
输出为空白(不显示任何内容).
如果我打电话
Invoke-TenTimes { $_ -eq $null }
Run Code Online (Sandbox Code Playgroud)
我得到10个true.事实上,我看到它$_是空的.
什么是填充的正确方法$_?
让我疯狂的是,如果我将此函数和调用放在同一个ps1文件中,它可以工作(但我想按需传递脚本块):
function Invoke-TenTimes
{
[CmdletBinding()]
param
(
[Parameter(Mandatory=$true, Position=0)]
[ScriptBlock]$Action
)
process
{
$digits = 0..10
$digits | % {
$Action.Invoke($_);
}
}
}
Invoke-TenTimes { $_ }
Run Code Online (Sandbox Code Playgroud)
小智 5
开始了:
$scriptblock = {param($number) Write-Host "Current Number is $number"}
function Invoke-TenTimes
{
[CmdletBinding()]
param
(
[Parameter(Mandatory=$true, Position=0)]
[ScriptBlock]$Action
)
$digits = 1..10
$digits | ForEach-Object{Invoke-Command -ScriptBlock $Action -Args $_}
}
Run Code Online (Sandbox Code Playgroud)
使用:
Invoke-TenTimes $scriptblock
Run Code Online (Sandbox Code Playgroud)
这是一个范围问题,传入的脚本块属于与其执行范围不同的范围。如果传入的脚本块不必引用其上下文中的变量,您可以简单地克隆脚本块以强制它位于您正在运行它的范围内。和
$action = [scriptblock]::Create($action)
Run Code Online (Sandbox Code Playgroud)
有趣的是,它一开始只是因为意外才起作用。它从脚本块所属的父范围获取 $_ ,该脚本块恰好位于 foreach-object 内部,这很好。
但是使用你的原始版本,然后运行这个
"gotcha" | % {
Invoke-TenTimes { $_ }
}
Run Code Online (Sandbox Code Playgroud)
你会发现你会遇到 10 次陷阱,因为 $_ 在你的调用者范围内不为 null,但它是一些东西。
| 归档时间: |
|
| 查看次数: |
3219 次 |
| 最近记录: |