2012-10-21 39 views
4

在編寫sh腳本時,是否認爲好的做法是在腳本末尾取消設置所有以前定義的全局變量?是否在腳本良好實踐中未定義全局變量?

如果例如,我執行我的腳本myscript使用。 (源)內建,像這樣

. myscript 

在執行腳本之後,shell會被腳本中定義的變量拋出。這似乎很糟糕(特別是如果被其他人使用)。

如果可以的話,我會完全擺脫sh(或bash)中的全局變量,但更多的時候不是他們是最差的解決方案:-)。

回答

10

這並不是真正執行腳本。它正在採購它,這使得shell在腳本中執行每個命令。如果要執行該腳本,你可以這樣做:

./myscript 

而且在這種情況下,沒有被設定在腳本中的環境變量會對你的shell的效果。

(
    a=7 
    echo $a 
) 
# The change in a doesn't get to here 

如果你真的需要源腳本,以便它可以做的事情一樣設置環境變量或更改當前目錄,那麼你可以使用括號隔離子shell中的變量如果你想解除你使用的變量,你會遇到相反的問題。如果用戶設置了一個名稱相同的變量,那麼最終會毀掉它。

1

不一定。

當你執行一個腳本時,它會執行一個新的shell和任何變量來設置腳本不會影響父shell。

如果你在shell本身上做了. myscript(而不是在腳本中),那麼變量設置將會存在並且可能會污染你的shell。

2

當編寫sh腳本時,在腳本的末尾取消設置所有以前定義的全局變量是否被認爲是良好的做法?

如果腳本正常執行(在子shell中,使用myscript),那麼沒有理由擔心在腳本中定義的變量(或函數)。當腳本停止執行而不會對調用shell造成損害時,它們會消失。

如果,例如,我執行使用.source)內建我的劇本的MyScript,這樣

. myscript 

執行腳本的外殼被污染,在腳本中定義的變量之後。這似乎很糟糕(特別是如果被其他人使用)。

來源的任何腳本都需要有一個非常好的原因來源(設置特定的環境變量或更改目錄是常見的原因)。任何將被其他人使用的腳本都應該是非常狂熱的,因爲它會忽略它偶然設置的任何變量,小心地首先使用明確命名的變量,並在完成時將它們全部取消設置。

或者,至少,如果我的shell中含有變量,我將不會獲取別人的腳本。我不經常在「配置文件」操作之外源文件,但是當我這樣做時,腳本被設計爲設置某些變量。它可以設置這些(如果沒有的話,它不會有用);但最好不要添加其他變量的隨機分類。如有必要,我製作另一個人的腳本的副本,並將其用於我自己的使用,或用消毒腳本包裝。

我有一個腳本,我用它來設置PATH(所以它或多或少都必須是有用的)。它開始:

ps_machine=$(uname -n) 
ps_pathset=no 
ps_pathoptsfile= 
for ps_file in \ 
     ${HOME}/.pathopts.$ps_machine \ 
     ${REAL_HOME:-$HOME}/.pathopts.$ps_machine \ 
     ${HOME}/.pathopts \ 
     ${REAL_HOME:-$HOME}/.pathopts 
do 
    ...40 lines of esoteric code... 
    ...some set ps_perl; some set ps_pathopts... 
done 

...5 lines of active code that set PATH... 

unset ps_pathset ps_pathoptsfile ps_pathopts ps_file ps_perl ps_machine 

我調用這個爲:

. mcpathset 

這個命令的另一種設計是:

export PATH=$(mcpathset) 

這裏,命令的輸出作爲新PATH的值。當你只需要設置一個變量時,這是一個可行的設計。如果您需要設置一套環境變量(例如,將環境配置爲使用特定的DBMS),則這樣做不太可行。

我不會用正常腳本來清理變量 - 那些不打算來源的變量。但對於源代碼腳本,我認爲這很重要。我懷疑每個人都同意我的觀點,很多人可能都不在乎。但我同意你的觀點 - 對於源代碼腳本來說乾淨非常重要。