2011-12-15 32 views
4

點源代碼powershell腳本時,我遇到了一些範圍問題。 假設我有一個劇本 'A.ps1':點源代碼腳本時PowerShell範圍衝突

$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 

爲什麼這種情況非常明顯。來自B.ps1的$VERSION變量被放入A.ps1的範圍並覆蓋該變量。事實上,這也發生在Write-Version以及A.ps1覆蓋B的版本,但是因爲Write-Version在B.ps1中被調用,所以我們仍然可以看到B的Write-Version函數的輸出。

這個問題當然是如何防止這個?我已經嘗試了各種範圍選項,但點擊採購時似乎不起作用。而且由於B.ps1中有函數需要在A的作用域中,所以只需調用B.ps1可能不是一個選項。

有沒有人有任何想法?

+1

有趣的問題。如果是我,我不會在兩個腳本中重複使用相同的變量名稱(如果它們在同一個會話中使用)。 – JNK 2011-12-15 13:54:05

+1

有關您的問題的一切都是有效的,所以都是答案(您應該使用模塊) - **除爲你的前提**。您聲明B輸出2.0和A輸出1.0。 (如果事實如此,你甚至不需要發佈這個問題!)實際上,A輸出2.0,這是你的觀點。 (是的,我知道這只是一個錯字,但是一個角色會有什麼不同:-) – 2011-12-15 17:38:56

+0

@msorens是的,謝謝你的發現。你的推理絕對正確。我將修改帖子。 – wensveen 2011-12-16 08:45:21

回答

1

您可以通過將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

模塊是在Powershell V2中創建的,以解決dot sourcing的這些類型的問題。使用psm1擴展名保存腳本,並使用Import-Module cmdlet代替代碼中的點源。

+0

感謝您的回答。我會標記雷恩的答案,因爲它有更多的信息。我希望我可以標記兩個。 – wensveen 2011-12-16 08:52:39

0

正如傢伙abouve提到的解決方案之一是將腳本轉換爲PS模塊。

但是,只要您不需要在全局源代碼的函數中使用點源函數(我面對該問題並且不確定是否有解決方法:question),您可以通過這種方式解決您的問題:

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 

的想法是使用&調用,而不是點採購(你可以在我的article瞭解他們,但它是沒有什麼好說的超過&調用的東西,而不將其添加到當前範圍和。調用並添加到範圍)。

而且,您仍然可以通過作用域修改器從ScopeB.ps1訪問全局作用域(這也在same article中有示例提及)。這解釋了$ overridenFromAntotherFile上面的腳本中的變量。