Столкновение области видимости PowerShell при сценариях точечного поиска - PullRequest
4 голосов
/ 15 декабря 2011

У меня возникают некоторые проблемы с областью действия при создании сценариев PowerShell. Предположим, у меня есть один скрипт «A.ps1»:

$VERSION = "1.0"

# Dot source B.ps1
. .\B.ps1

function Write-Version { Write-Host "A.ps1 version $VERSION" }
Write-Version

и скрипт B.ps1

$VERSION = "2.0"
function Write-Version { Write-Host "B.ps1 version $VERSION" }
Write-Version

Результат работы A.ps1 будет:

B.ps1 version 2.0
A.ps1 version 2.0

Почему это происходит, совершенно очевидно. Переменная $VERSION из B.ps1 помещается в область видимости A.ps1 и перезаписывает эту переменную. Действительно, это также происходит с Write-Version, но здесь A.ps1 перезаписывает версию B, но поскольку Write-Version вызывается в B.ps1 до того, как это произойдет, мы все равно можем увидеть выходные данные функции Write-Version B.

Вопрос, конечно, как это предотвратить ?? Я пробовал различные варианты области видимости, но, похоже, это не работает при точечном поиске. А так как в B.ps1 есть функции, которые мне нужны в области видимости A., просто вызвать B.ps1, вероятно, не вариант.

У кого-нибудь есть идеи?

Ответы [ 3 ]

2 голосов
/ 15 декабря 2011

Вы можете сделать это, сделав B.ps1 модулем и переименовав его в B.psm1.Добавьте Export-ModuleMember, чтобы сделать ваши функции доступными для других сценариев.

Это будет B.psm1:

$VERSION = "2.0"
function Write-Version { Write-Host "B.ps1 version $VERSION" }
Write-Version

# Only items specified here will be exported. If Export-ModuleMember is not used,
# ALL members (functions, variables, and aliases) will be exported. In this case
# if $VERSION was exported, $VERSION will be set to "2.0" in script A.ps1
Export-ModuleMember -Function Write-Version

И A.ps1 будет:

$VERSION = "1.0"

# Import B.psm1
Import-Module .\B.psm1

function Write-Version { Write-Host "A.ps1 version $VERSION" }
Write-Version

# Use B.psm1's `Write-Version` function
B\Write-Version
2 голосов
/ 15 декабря 2011

Модули были созданы в Powershell V2 для решения подобных проблем с точечным источником. Сохраните сценарий с расширением psm1 и используйте командлет Import-Module вместо точечного поиска в коде.

0 голосов
/ 03 марта 2013

Как уже упоминали ребята, одним из решений является преобразование вашего скрипта в PS-модуль.

Но, как только вам не нужно ставить функции-точки в функциях на глобальный источник (я сталкиваюсь с этимпроблема и не уверен, есть ли способ ее решить: вопрос ) вы можете решить свою проблему следующим образом:

ScopesA.ps1:

$VERSION = "1.0"
$overridenFromAntotherFile = "original"

# Invoke ScopesB.ps1 via &
& .\ScopesB.ps1

Function Write-Version { Write-Host "ScopesA.ps1 version $VERSION" }
Write-Version

Write-Host $overridenFromAntotherFile

ScopesB.ps1:

$VERSION = '2.0'
$global:overridenFromAntotherFile = 'overriden'
function Write-Version { Write-Host "ScopesB.ps1 version $VERSION" }
Write-Version

Вывод:

ScopesB.ps1 version 2.0
ScopesA.ps1 version 1.0
overriden

Идея заключается в использовании & invocation вместо точечного поиска (о них вы можете прочитать в моей статье , ноне так много, чтобы сказать больше, чем & вызывает что-то, не добавляя его в текущую область, а. вызывает и добавляет в область).

И, тем не менее, вы можете получить доступ к глобальной области из ScopeB.ps1 через модификатор области (также упоминается в той же статье с примерами).Это объясняется с помощью переменной $ overridenFromAntotherFile в приведенном выше сценарии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...