我正在尝试在PowerShell ISE中自动创建一组标签
我开始使用
等功能function Start-NewTab($name, [ScriptBlock]$scriptBlock)
{
$tab = $psISE.PowerShellTabs.Add()
$tab.DisplayName = $name
sleep 2
$tab.Invoke($scriptBlock)
}
然而,当我像这样运行时
$v = "hello world"
Start-NewTab "Test" { $v }
hello world
未显示,与后面的法词
function Test-ScriptBlock([ScriptBlock]$sb) { & $sb }
Test-ScriptBlock { $v }
这里发生了什么,我该如何解决?
答案 0 :(得分:1)
“Tab”容器等同于ISE中的运行空间(或powershell execution environment)。由于您正在创建新的Tab(即powershell执行环境),因此在该执行环境中未定义变量v。在新的执行环境中评估scriptblock并输出v(nothing)的值。
如果你试图通过明确提到应该找到变量的范围来尝试获取scriptblock中的变量,那么很容易看出Test-Scriptblock的变量分辨率与Start-NewTab的情况有何不同。
PS>Test-ScriptBlock { get-variable v -scope 0}
Get-Variable : Cannot find a variable with name 'v'.
PS>Test-ScriptBlock { get-variable v -scope 1}
Get-Variable : Cannot find a variable with name 'v'.
PS>Test-ScriptBlock { get-variable v -scope 2} # Variable found in grandparent scope (global in the same execution environment)
Name Value
---- -----
v hello world
PS>Start-NewTab "Test" { get-variable v -scope 0 } # global scope of new execution environment
Get-Variable : Cannot find a variable with name 'v'.
PS>Start-NewTab "Test" { get-variable v -scope 1 } # proof that scope 0 = global scope
Get-Variable : The scope number '1' exceeds the number of active scopes.
您的问题的一种解决方法是在scriptblock中定义您的变量:
Start-NewTab "Test" { $v = "hello world";$v }
修改:还有一件事,你的标题提到'封闭'。 Powershell中的Scriptblocks不是闭包,但是您可以从scriptblock创建闭包。但是,这对您描述的问题没有帮助。
Edit2:另一种解决方法:
$v = "hello world"
Invoke-Expression "`$script = { '$v' }"
Start-NewTab "test" $script
答案 1 :(得分:0)
或者只是先创建脚本块。
$v={"Hello world"}
start-newtab "test" $v
但你必须牢记范围。
答案 2 :(得分:0)
我知道这是一个老问题,但我最近找到了解决这个问题的新方法。这可能对某些人有用。
使用环境变量:
function Start-NewTab($name, [ScriptBlock]$scriptBlock)
{
$tab = $psISE.PowerShellTabs.Add()
$tab.DisplayName = $name
sleep 2
$tab.Invoke($scriptBlock)
}
$env:v = "hello world"
Start-NewTab "Test" { $env:v }