2010-02-25 142 views
2

我有一個變量,這個變量對於我的大多數應用程序都稱爲「電子郵件」。我還想在其中一個腳本中使用「emails」作爲參數的名稱。我需要在同一個腳本中引用兩個變量的值。理想情況下,會有一種方法來引用使用模塊/命名空間或東西,也許有但我不知道它。你可以看到我如何破解這個,但它很醜,容易出錯。有沒有更好的辦法?PowerShell變量衝突

# PowerShell v1 
# Some variable names are very common. 
param ($emails) 

# My Hack 
# We need to save current value so we have it after we source in variables below. 
$emails0=$emails 

# Below is going to load a variable called "emails" which will overwrite parm above. 
. C:\load_a_bunch_of_global_variables.ps1 
+0

爲什麼你在C'$ emails'變量:\ load_a_bunch_of_global_variables.ps1腳本?它的目的是什麼? – stej 2010-02-25 06:41:02

+0

這是一個可以安裝在任何文件夾中的框架,單個「衆所周知的固定」文件是C:\中的一個文件。它加載框架的所有選項/配置。我用它組成框架的大部分腳本。該文件的名稱已更改。 – 2010-02-25 13:34:47

+1

當然,請記住,升級到V2後升級到模塊是我的建議#1。 – stej 2010-02-25 14:09:31

回答

6

這是因爲文件說:(點採購運營商),以便在腳本中的項目是呼叫範圍的一部分運行的腳本。

在這種情況下,我將轉換C:\load_a_bunch_of_global_variables.ps1到一個模塊,並通過作爲$emails參數或導出設置$script:emails變量模塊中的功能。然後該變量不會與父腳本中的變量發生衝突。

有關模塊的更多信息,您可以使用get-help about_modules


我會盡量避免在腳本中使用全局變量。

爲什麼?因爲它是一種代碼味道(正如程序員所說)。用一個腳本就沒有問題。如果兩個腳本使用相同的全局變量並只能讀取,則可能可以接受。但是,如果它們中的任何一個改變了價值,那麼可能會有不愉快的衝突。

在某些情況下,Get-Variable -scope 1 -name myvariable會有所幫助,但我只會在模塊或短腳本(與全局變量相同的原因)的封閉代碼段中使用它。

+0

不要認爲這些在v1中可用。我只是選擇了這一點,但擔心如果我需要安裝v2,我會遇到更多麻煩,所以我現在堅持使用v1。 – 2010-02-25 06:10:03

+0

不,模塊在V1中可用。不過,V2帶來了很多新功能,絕對值得升級到V2;) – stej 2010-02-25 06:18:14

+0

謝謝。我意識到全局變量存在的問題,但它們確實是需要的,或者我需要編寫一個API來獲取它們,這使設計變得複雜。我正在將應用程序從ksh移植到PowerShell。在ksh中,我不關心漂亮的命令行名稱,因爲在ksh中我會使用「-e」而不是「-emails」和「-p_emails」或類似的東西,看起來很愚蠢。試圖在這裏得到正確的可讀性和優雅組合。由於全球通常非常獨特,因此大多數變量沒有衝突。 – 2010-02-25 13:40:17

0

你可以在腳本中使用$ global:var name從腳本訪問你的全局變量,你可以在腳本中使用局部範圍,並且不會碰撞。如果你 。源代碼您將覆蓋全局變量。

對於防爆如果有一個腳本

$Crap ="test" 
$Crap 

你運行你得到你想要的東西流動的命令。在第2行中,我們運行腳本,並且var不會發生衝突,但是如果使用a運行第4行中的腳本。來源你得到你正在發現哪些由於這種方式。操作符

1:PS C:\Users\Adam> $crap = "hi" 
2:PS C:\Users\Adam> .\test.ps1 
test 
3:PS C:\Users\Adam> $crap 
hi 
4:PS C:\Users\Adam> . .\test.ps1 
test 
5:PS C:\Users\Adam> $crap 
test 
6:PS C:\Users\Adam> 

如果添加以下行腳本運行

$global:crap; 

你會得到

PS C:\Users\Adam> .\test.ps1 
test 
hi 
1

重新運行和stej都幫了我。

我仍然希望使用「。file.ps1」在文件中源代碼,但在我的load_a_bunch_of ... ps1文件中將「[email protected]」更改爲「$ global:emails = foo @ yahoo。 com「解決了這個問題。當我有一個局部變量和一個全局變量,並且當只有一個變量需要處理時,我現在可以使用全局關鍵字來引用變量,我可以省略全局關鍵字。

1

雖然可以使用Get-Variable -scope訪問調用堆棧的任意級別的變量,但在這種情況下,使用腳本:修飾符(例如)可以更輕鬆地獲取頂級(至腳本)變量。

$script:emails 
+0

Keith,我不確定我們是否都以同樣的方式理解它。試試這個:「param('$ emails)'r'n' $ emails'r'n' $ script:emails'r'n 。\ s2.ps1'r'n' $ emails'r'n' $ script:emails「> s1.ps1; '$ emails =「from s2」'> s2.ps1; \ s1.ps1測試。輸出是來自s2的測試測試,來自s2 – stej 2010-02-25 07:17:52

+0

哦,我看到 - 腳本範圍內的變量名稱發生衝突。 FWIW當我傾向於有一堆需要相同數據的不同腳本(構建腳本)時,我傾向於使用其中定義的一些變量(BuildVars.ps1)創建腳本。所以,當我用C++進行編程時,我忽略了全局變量,但在PowerShell中編寫腳本時,我有點勉強。 – 2010-02-25 16:21:38