Когда я пишу сложные сценарии PowerShell, я использую для разделения сценариев на отдельные файлы:
main.ps1
, чтобы содержать логику imports\xxxx.ps1
, imports\yyyy.ps1
,... to предоставляет пользовательские функции
Файл main.ps1
импортирует в текущую область функции с помощью команды точки после вычисления пути относительно текущего каталога.Пример:
$CurrentDirectory = Split-Path -Parent $MyInvocation.MyCommand.Definition
. "$CurrentDirectory\Imports\Maths.ps1"
Process-Multiply -x 10 -y 10 # assuming there's a function in the maths.ps1
Это работает, пока я не перезаписываю переменные в импортированных скриптах.Например, если мои подписчики снова объявляют переменную $CurrentDirectory
, она фактически перезаписывает переменную из основного сценария.Я думаю, это из-за точечной нотации (в противоположность & нотации).
Есть ли способ избежать этого?Возможно ли иметь «локальную» переменную для скрипта?
Вот полный воспроизводимый пример:
Файл main.ps1
:
$CurrentDirectory = Split-Path -Parent $MyInvocation.MyCommand.Definition
Write-Host "`$CurrentDirectory from main.ps1 : $CurrentDirectory"
. "$CurrentDirectory\Imports\Maths.ps1"
Write-Host "`$CurrentDirectory from main.ps1 : $CurrentDirectory"
Process-Multiply -x 10 -y 10
Файл Imports\Maths.ps1
:
$CurrentDirectory = Split-Path -Parent $MyInvocation.MyCommand.Definition
function Process-Multiply{
param(
[Parameter(Mandatory=$true)][int]$x,
[Parameter(Mandatory=$true)][int]$y
)
$x * $y
}
При запуске сценария main.ps1 вывод:
$CurrentDirectory from main.ps1 : C:\temp\xx
$CurrentDirectory from main.ps1 : C:\temp\xx\Imports
100
Как видите, переменная $CurrentDirectory
переопределяется в подпрограмме.
PS: я знаю, что мог бы переименовать переменную в нижнем индексе, но в более широком масштабе с централизованными сценариями было бы трудно обеспечить уникальность имен переменных.
PPS: реальный мирСценарий, в котором мне нужен путь к каталогу текущего скрипта, заключается в загрузке пользовательского модуля из сборки ac #.Сборка находится в подкаталоге скрипта загрузчика.
PPPS (!): Я должен придерживаться PS v4