簡體   English   中英

powershell 點源 function 參數覆蓋局部變量

[英]powershell dot sourced function parameter overwrites local variables

我正在使用 powershell 點源來設置當前 scope 中的變量,並且遇到了一個有趣的功能。

function 的參數似乎也會覆蓋任何同名的局部變量。

這是預期的嗎?

我是否應該只使用 $global:MyVar 從其他腳本中設置本地 scope 中的變量?

# Given
function TestX([string]$X) 
{
   Write-Host "`$X = $X" 
}

# And variable $X
# Note that the variable name is the same as the parameter name in 'TestX'
$X = "MyValue"

PS> TestX $X
MyValue

PS> $X; TestX "123456"
MyValue
123456

PS> $X; . TestX "123456"
MyValue
123456

PS> $X; . TestX "123456"
123456
123456

編輯:擴大我想要完成的事情......

我有一組用於構建過程的腳本。 這些腳本用於針對多個環境。 每個環境(DEV、TEST、QA、PROD)都有不同的配置,它們應用不同的規則/設置/等。 這些配置存儲在目錄中。 在這些設置中,有一些 powershell 文件用於為該特定環境設置腳本范圍的設置。 比如目標服務器URL,目標服務器UNC等。

在構建過程腳本中有一個 function Confirm-TargetEnvironmentVariables。 顧名思義,它檢查環境變量是否已加載,如果沒有,則加載它們。 此 function 散布在各種腳本文件/函數中,以確保當 function 使用這些腳本范圍變量之一時,它已被設置。

我曾經用點源調用的是這個 function。

function Confirm-TargetEnvironmentVariables([string]$TargetEnvironment) 
{
   ...
}

# Like this..
. Confirm-TargetEnvironmentVariables "PROD"

這一切都很好。 直到我需要在來自多個環境的加載變量之間切換(例如,為了從 PROD 刷新 TEST,我需要來自兩者的變量信息)。 事實上這仍然有效,除了在調用 Confirm-TargetEnvironmentVariables 的腳本中我已經有一個名為 $TargetEnvironment 的變量。 所以我試圖這樣做:

$SourceEnvironment = "PROD"
$TargetEnvironment = "TEST"

. Confirm-TargetEnvironmentVariables $SourceEnvironment

# Do stuff with loaded "PROD" variables...

. Confirm-TargetEnvironmentVariables $TargetEnvironment

# Do stuff with loaded "TEST" variables...

但發生的事情是這樣的:

$SourceEnvironment = "PROD"
$TargetEnvironment = "TEST"

. Confirm-TargetEnvironmentVariables $SourceEnvironment

# Do stuff with loaded "PROD" variables...
# The value of $TargetEnvironment has been set to "PROD" by dot-sourcing!!

. Confirm-TargetEnvironmentVariables $TargetEnvironment

# Do stuff with loaded... "PROD" variables!!!

因此,這應該有望提供更多背景信息。 但最終它仍然提出了一個問題,為什么 dot-sourcing 在將變量引入本地 scope 時包含參數變量。 這是設計使然嗎? 不過,我想不出這種情況是理想的行為。

應該只使用 $global:MyVar 從其他腳本中設置本地 scope 中的變量嗎?

我建議您避免編寫需要點源才能正常工作或寫入全局變量的函數。

相反,使用Set-Variable-Scope參數寫入調用 scope 中的變量:

function Test-SetVariable
{
  param([string]$Name,$Value)

  # '1' means "one level up", so it updates the variable in the caller's scope
  Set-Variable -Name $Name -Value $Value -Scope 1
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM