[英]How to refer to a PowerShell function defined in a parent scope?
I'm writing a PowerShell script that runs a couple of background jobs.我正在编写一个运行几个后台作业的 PowerShell 脚本。 Some of these background jobs will use the same set of constants or utility functions, like so:
其中一些后台作业将使用相同的常量或实用函数集,如下所示:
$FirstConstant = "Not changing"
$SecondConstant = "Also not changing"
function Do-TheThing($thing)
{
# Stuff
}
$FirstJob = Start-Job -ScriptBlock {
Do-TheThing $using:FirstConstant
}
$SecondJob = Start-Job -ScriptBlock {
Do-TheThing $using:FirstConstant
Do-TheThing $using:SecondConstant
}
If I wanted to share variables (or, in this case, constants) in child scopes, I'd prefix the variable references with $using:
.如果我想在子作用域中共享变量(或者,在这种情况下是常量),我会在变量引用前加上
$using:
。 I can't do that with functions, though;不过,我不能用函数来做到这一点; running this code as-is returns an error:
按原样运行此代码会返回错误:
The term 'Do-TheThing' is not recognized as the name of a cmdlet, function, script file, or operable program.
My question is this: How can my background jobs use a small utility function that I've defined in a higher scope?我的问题是:我的后台作业如何使用我在更高的 scope 中定义的小型实用程序 function?
If the function in the higher scope is in the same (non-)module scope in the same session , your code implicitly sees it, due to PowerShell's dynamic scoping. If the function in the higher scope is in the same (non-)module scope in the same session , your code implicitly sees it, due to PowerShell's dynamic scoping.
However, background jobs run in a separate process (child process), so anything from the caller's scope must be passed explicitly to this separate session.但是,后台作业在单独的进程(子进程)中运行,因此调用者的 scope 中的任何内容都必须显式传递给这个单独的 session。
This is trivial for variable values, with the $using:
scope , but less obvious for functions , but it can be made to work with a bit of duplication, by passing a function's body via namespace variable notation :这对于变量值来说是微不足道的,使用
$using:
scope ,但对于函数来说不太明显,但它可以通过命名空间变量表示法传递函数体来实现一些重复:
# The function to call from the background job.
Function Do-TheThing { param($thing) "thing is: $thing" }
$firstConstant = 'Not changing'
Start-Job {
# Define function Do-TheThing here in the background job, using
# the caller's function *body*.
${function:Do-TheThing} = ${using:function:Do-TheThing}
# Now call it, with a variable value from the caller's scope
Do-TheThing $using:firstConstant
} | Receive-Job -Wait -AutoRemoveJob
The above outputs 'thing is: Not changing'
, as expected.正如预期的那样,上面的输出
'thing is: Not changing'
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.