PowerShell:如何在调用ScriptBlock时设置$_变量?
在PowerShell中为ScriptBlock设置$_值的几种方法
$(别名$PSItem)是PowerShell的管道自动变量,仅在管道处理、Where-Object/ForEach-Object这类cmdlet的绑定场景下会自动赋值。直接调用ScriptBlock的Invoke()方法或错误传递ScriptBlock变量时,不会自动设置$,下面是具体解决办法:
1. 通过管道调用ScriptBlock
这是最贴近原生管道场景的方式,用调用操作符&配合管道传递值,自动绑定$_:
$f = { $_.Contains('pp') } 'apple' | & $f # 输出 True
针对你遇到的ForEach-Object报错问题,不要直接写%$f,改用以下两种正确写法:
# 写法1:显式指定-Process参数 $f = { $_.Contains('pp') } 'apple' | ForEach-Object -Process $f # 输出 True # 写法2:用&通过管道调用 'apple' | & $f
2. 用InvokeWithContext手动绑定$_
如果需要直接调用ScriptBlock的方法,可以用InvokeWithContext手动定义$_的值:
$f = { $_.Contains('pp') } # 第二个参数传入PSVariable对象,指定$_的取值为'apple' $f.InvokeWithContext($null, [System.Management.Automation.PSVariable]::new('_', 'apple')) # 输出 True
同时传递参数和绑定$_的场景:
$ff = { echo "args: $args`nauto: $_" } # 第一个参数是$args的取值数组,第二个是自动变量定义数组 $ff.InvokeWithContext(@('自定义参数'), [System.Management.Automation.PSVariable]::new('_', 'apple')) # 输出: # args: 自定义参数 # auto: apple
3. 让ScriptBlock兼容两种调用方式
如果想让ScriptBlock既能在管道/Where-Object中使用,又能直接Invoke,可以在ScriptBlock内做兼容处理:
$f = { # 优先用传入的参数,没有则用$_ $target = $args[0] ?? $_ $target.Contains('pp') } # 管道场景正常工作 'apple' | Where-Object $f # 直接Invoke也能运行 $f.Invoke('apple') # 输出 True
内容的提问来源于stack exchange,提问作者Sled
相关产品推荐
相关产品推荐

