PowerShell 范围标识符

3

我是一个PowerShell新手,正在努力更好地理解作用域。是否有一种方法可以从作用域内部识别作用域?是否有一些变量或函数可以给出作用域名称、作用域GUID或某种作用域ID?

比如说,我怎样才能知道本地作用域是否是全局作用域?


请查看我大幅改写后的答案,现在显示更为健壮的测试。 - mklement0
1个回答

3
例如,我怎样才能知道局部作用域是全局作用域?
[bool] $isGlobalScope = -not $(try { Get-Variable -Scope 1 PSHOME } catch { })

$PSHOME 是一个带有选项 AllScope自动变量,因此根据定义在每个作用域中都存在。它还具有选项 Constant,这意味着它既不能删除也不能修改。

通过要求从父级作用域 -Scope 1 检索此变量的 Get-Variable,如果您在全局作用域中,则操作将失败,因为全局作用域是整个作用域层次结构的根,因此没有父级。

总之:

  • 如果您不在全局作用域中,则 Get-Variable 调用将成功并返回一个非空字符串(PowerShell的主目录路径)。

    • 布尔运算符 -not 将该字符串强制转换为布尔值 ([bool]),这会评估为 $false,因为非空字符串被认为是$true(不考虑其内容)并且应用了否定。
  • 如果您在全局作用域中,则尝试访问 -Scope 1 会导致一个语句终止错误,触发try / catch / finally语句的catch块。

    • 由于catch块没有采取任何操作,它就像表达式上下文中的$null一样。
    • -not$null强制转换为布尔值。在布尔上下文中,$null$false,因此使用-not进行否定评估为$true,表示代码在全局作用域中运行。

注意:线程/后台作业和远程会话具有它们自己的全局作用域,上述测试无法区分它们。


注意:这个答案的原始形式建议使用(Get-PSCallStack).Count -eq 1作为测试;Get-PSCallStack输出描述当前范围调用链的[System.Management.Automation.CallStackFrame]实例,以相反的顺序。 因此,这个测试无法检测通过点操作符引入到全局范围中运行的情况。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接