【问题标题】:Module scope gets duplicated for every script每个脚本的模块范围都重复
【发布时间】:2019-05-13 13:54:57
【问题描述】:

我有一个模块和运行简单用户脚本的脚本。我想让用户脚本尽可能简单,这就是我使用Import-Module-Global 标志的原因。我对模块“私有”变量有疑问。就我而言,我有这个变量的 2 个副本。我可以只实现一个副本吗?

下面是一个简单的例子。您可以通过将3个文件放在同一个文件夹中并执行ScriptRunner.ps1来运行。

Module.psm1

function Invoke-UserScript
{
    param($Path)

    $Script:UserScriptFailed = $false
    & $Path
    return $Script:UserScriptFailed
}

function New-Something
{
    $Script:UserScriptFailed = $true
}

function Write-Var
{
    Write-Host "Write-Var output: $Script:UserScriptFailed"
}

Export-ModuleMember -Function Invoke-UserScript
Export-ModuleMember -Function New-Something
Export-ModuleMember -Function Write-Var

ScriptRunner.ps1

Set-Location $PSScriptRoot
Import-Module -Name (Resolve-Path '.\Module.psm1') -Global
$failed = Invoke-UserScript -Path '.\UserScript.ps1'
Write-Output "ScriptRunner output: $failed"

UserScript.ps1

New-Something
Write-Var

在我的示例函数中,New-SomethingUserScriptFailed 设置为 $true。但是一旦UserScript.ps1 完成,ScriptRunner.ps1 就会看到$false 的值。

输出:

Write-Var output: True
ScriptRunner output: False

【问题讨论】:

  • 这是意料之中的——$script: 指的是从模块的导出函数中调用时的模块范围,ScriptRunner.ps1 不是模块的一部分
  • @MathiasR.Jessen ScriptRunner.ps1 不是模块的一部分,也不是指UserScriptFailed 变量,我们在这里没问题。问题是& $Path 创建了这个变量的新副本。而这一行在一个模块内。
  • 您也许可以使用Export-ModuleMember -Variable ...,但我不确定这将如何在script: 范围内工作。另一种方法可能是将UserScriptFailed 移动到global-scope,但这不是最好的选择......
  • 你想达到什么目的?
  • 如果你想在多个 ps1 文件之间共享一个变量,你可以尝试将变量作为 ref-parameter 注入

标签: powershell powershell-module


【解决方案1】:

您可以尝试点源您要检查的脚本:

function Invoke-UserScript
{
    param($Path)

    $Script:UserScriptFailed = $false
    # Sourcing may add the functions to the current scope
    . $Path
    & $Path
    return $Script:UserScriptFailed
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-01
    • 2016-02-27
    • 2015-10-04
    • 1970-01-01
    • 1970-01-01
    • 2013-10-23
    • 1970-01-01
    相关资源
    最近更新 更多