Область модуля дублируется для каждого скрипта

У меня есть модуль и скрипт, который запускает простые пользовательские скрипты. Я хочу, чтобы пользовательский скрипт был максимально простым, поэтому я использую Import-Module с флагом -Global. У меня проблема с переменной "private" модуля. В моем случае у меня есть 2 копии этой переменной. Могу ли я получить только одну копию?

Ниже приведен простой пример. Вы можете запустить, поместив 3 файла в одну папку и выполнив ScriptRunner.ps1.

Модуль.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"

Пользовательский скрипт.ps1

New-Something
Write-Var

В моем примере функция New-Something устанавливает UserScriptFailed в $true. Но как только UserScript.ps1 заканчивает работу, ScriptRunner.ps1 видит $false значение.

Выход:

Write-Var output: True
ScriptRunner output: False

Этого следовало ожидать - $script: относится к области модуля при вызове из экспортируемой функции модуля, а ScriptRunner.ps1 не является частью модуля.

Mathias R. Jessen 13.05.2019 16:11

@MathiasR.Jessen ScriptRunner.ps1 не является частью модуля и не относится к переменной UserScriptFailed, здесь все в порядке. Проблема в том, что & $Path создает новую копию этой переменной. И эта строка находится внутри модуля.

Zergatul 13.05.2019 16:18

Возможно, вы могли бы использовать Export-ModuleMember -Variable ..., но я не уверен, как это будет работать с прицелом script:. Другим способом может быть перемещение UserScriptFailed в global-прицел, но это не самая лучшая радость...

Moerwald 13.05.2019 16:57

Чего вы хотите достичь?

Moerwald 13.05.2019 16:58

Если вы хотите разделить переменную между несколькими ps1-файлами, вы можете попробовать внедрить переменную в качестве параметра ссылка.

Moerwald 13.05.2019 17:03

@Moerwald Я хочу проверить пользовательский скрипт с помощью моего модуля. Пользователь создает простой скрипт с командами из моего модуля (я разбираю его скрипт и проверяю, использует ли он только разрешенные команды). Короче говоря, я хочу получить 2 значения True в своем выводе.

Zergatul 13.05.2019 17:10

Глобальная переменная @Moerwald или экспортированная переменная неверны, так как пользователь может получить к ней доступ

Zergatul 13.05.2019 17:11

Давайте продолжить обсуждение в чате.

Moerwald 13.05.2019 17:19
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
8
26
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете попробовать указать исходный код скрипта, который хотите проверить:

function Invoke-UserScript
{
    param($Path)

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

Другие вопросы по теме