2012-06-11 44 views
1

語境:如何以編程方式取消設置全局bash變量/管理bash全局範圍?

我們有幾件我們的基礎設施,由大集Bash腳本的是通過文件的source命令,包括(經常鏈包含)所創建符合彼此交互管理我們使用的標準Bash模板。我知道這是一個應該可能永遠不會被允許的情況,但這是我們所擁有的。

模板基本上是這樣的:

set_params() { 
    #for parameters in a file that need to be accessed by other methods 
    #in that file and have the same value from initialization of that 
    #file to its conclusion: 
    global_param1=value 

    #left blank for variables that are going to be used by other methods 
    #in the file, but don't have a static value assigned immediately: 
    global_param2= 
} 

main_internals() { 
    #user-created code goes here. 
} 

main() { 
    set_params 
    #generic setup stuff/traps go here 
    main_internals arg arg arg 
    #generic teardown stuff goes here 
} 

採用這種結構,我們有文件包括通過source命令其他文件,然後調用包含文件main方法,它包裝並進行模塊化大部分操作不夠好。

問題:

一些與此基礎結構的最棘手的問題時,出現一個新的模塊添加到使用,用於其他地方,unrelatedly一個全局變量名的代碼庫,在同一source d鏈/文件集。也就是說,如果file1.sh有一個名爲myfile的變量,它用於某些事情,然後source的file2.sh,然後用myfile做一些更多的東西,寫file2.sh的人不知道(在很多情況下他們不能期望 - 有一個鏈接在一起的 lot),他們可能會在file2.sh中放入一個名爲myfile的非本地變量,在file1.sh中更改具有相同名稱的變量中的值。

問:

假設全局變量名稱衝突會出現,而荷蘭國際集團local一切都無法完全SOLV問題是否有一種方法可以以編程方式取消設置在特定函數執行過程中在全局範圍內設置的所有變量,或者在特定函數執行期間調用這些變量?有沒有一種方法可以取消設置,而不用取消設置相關文件所保存的相同名稱的其他變量?source有問題的腳本?

答案很可能是「不」,但是在環顧四周後,除了「在完成使用後跟蹤變量名並取消設置任何內容」之外,沒有發現其他內容(這將不可避免地導致代價高昂的錯誤),我想我會問。

換個角度看:有沒有辦法讓Bash的第三個範圍工作? 「本地功能」和「在此文件中運行的所有內容以及此文件的任何文件d」之間的內容「?

回答

3

以下是未經測試的。

您可以節省大量的變量是這樣的:

unset __var __vars 
saveIFS=$IFS 
IFS=$'\n' 
__vars=($(declare -p)) 
IFS=$saveIFS 

或保存通過改變倒數線之上,並依據一個共同的前綴:

__vars=($(declare -p "${[email protected]}")) 

然後你就可以你需要取消設置的那些到:

unset foo bar baz 

或取消或修改它們基於一個共同的前綴:

unset "${[email protected]}" 

要恢復變量:

for __var in "${__vars[@]}" 
do 
    $i 
done 

當心

  • 變量與嵌入的新行會做錯事
  • 與空白值會做錯事
  • 如果匹配前綴參數擴展返回空結果,則declare -p命令將返回全部變量。

另一種技術,它是更多的選擇性可能是你知道具體是哪個變量在當前函數中使用,所以你可以有選擇地保存和恢復它們:

# save 
for var in foo bar baz 
do 
    names+=($var) 
    values+=("${!var}") 
done 

# restore 
for index in "${!names[@]}" 
do 
    declare "${names[index]}"="${values[index]}" 
done 

使用的變量名,而不是「無功」, 「索引」,「名稱」和「值」,這些不太可能與其他人發生衝突。使用export而不是declare內部函數,因爲declare強制變量爲局部變量,但隨後會導出可能會導致或可能不會導致不良後果的變量。

建議:更換混亂,使用更少的全局變量或使用不同的語言。

否則,試試我上面概述的內容,看看你是否可以使用你的代碼工作。

+0

這似乎是一個合理的解決方案,對於這個問題我多年來一直提出很多不太合理的解決方案。謝謝。 :-) – ghoti