我是一个PowerShell新手,正在努力更好地理解作用域。是否有一种方法可以从作用域内部识别作用域?是否有一些变量或函数可以给出作用域名称、作用域GUID或某种作用域ID?
比如说,我怎样才能知道本地作用域是否是全局作用域?
我是一个PowerShell新手,正在努力更好地理解作用域。是否有一种方法可以从作用域内部识别作用域?是否有一些变量或函数可以给出作用域名称、作用域GUID或某种作用域ID?
比如说,我怎样才能知道本地作用域是否是全局作用域?
[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]
实例,以相反的顺序。
因此,这个测试无法检测通过点操作符引入到全局范围中运行的情况。