在 bash 和幾乎所有其它 shell 中,使用者可以定義環境變數,這些環境變數在以 ASCII字串儲存。環境變數的最便利之處在於:它們是 UNIX 進程模型的標準部分。這意味著:環境變數不僅由 shell指令碼獨用,而且還可以由編譯過的標準程式使用。當在 bash 中“匯出”環境變數時,以後啟動並執行任何程式,不管是不是 shell指令碼,都可以讀取設定。一個很好的例子是 vipw 命令,它通常允許 root 使用者編輯系統口令檔案。通過將 EDITOR環境變數設定成喜愛的文字編輯器名稱,可以配置 vipw,使其使用該編輯器,而不使用
vi,如果習慣於 xemacs 而確實不喜歡vi,那麼這是很便利的。
在 bash 中定義環境變數的標準方法是:
$ myvar='This is my environment variable!' |
以上命令定義了一個名為 "myvar" 的環境變數,並包含字串 "This is my environmentvariable!"。以上有幾點注意事項:第一,在等號 "="的兩邊沒有空格,任何空格將導致錯誤(試一下看看)。第二個件要注意的事是:雖然在定義一個字時可以省略引號,但是當定義的環境變數值多於一個字時(包含空格或製表鍵),引號是必須的。
第三,雖然通常可以用雙引號來替代單引號,但在上例中,這樣做會導致錯誤。為什麼呢?因為使用單引號禁用了稱為擴充的 bash特性,其中,特殊字元和字元系列由值替換。例如,"!" 字元是曆史擴充字元,bash通常將其替換為前面輸入的命令。(本系列文章中將不講述曆史擴充,因為它在 bash 編程中不常用。有關曆史擴充的詳細資料,請參閱 bash協助頁中的“曆史擴充”一節。)儘管這個類似於宏的功能很便利,但我們現在只想在環境變數後面加上一個簡單的驚嘆號,而不是宏。
現在,讓我們看一下如何實際使用環境變數。這有一個例子:
$ echo $myvarThis is my environment variable! |
通過在環境變數的前面加上一個 $,可以使 bash 用 myvar 的值替換它。這在 bash 術語中叫做“變數擴充”。但是,這樣做將怎樣:
我們希望回顯 "fooThis is my environmentvariable!bar",但卻不是這樣。錯在哪裡?簡單地說,bash變數擴充設施陷入了困惑。它無法識別要擴充哪一個變數:$m、$my、$myvar 、$myvarbar 等等。如何更明確清楚地告述 bash引用哪一個變數?試一下這個:
$ echo foo${myvar}barfooThis is my environment variable!bar |
如您所見,當環境變數沒有與周圍文本明顯分開時,可以用花括弧將它括起。雖然 $myvar 可以更快輸入,並且在大多數情況下正確工作,但${myvar}卻能在幾乎所有情況下正確通過文法分析。除此之外,二者相同,將在本系列的餘下部分看到變數擴充的兩種形式。請記住:當環境變數沒有用空白(空格或製表鍵)與周圍文本分開時,請使用更明確的花括弧形式。
回想一下,我們還提到過可以“匯出”變數。當匯出環境變數時,它可以自動地由以後啟動並執行任何指令碼或可執行程式環境使用。shell指令碼可以使用 shell 的內建環境變數支援“到達”環境變數,而 C 程式可以使用 getenv() 函數調用。這裡有一些 C程式碼範例,輸入並編譯它們 -- 它將協助我們從 C 的角度理解環境變數:
myvar.c -- 樣本環境變數 C 程式
#include <stdio.h>#include <stdlib.h>int main(void) { char *myenvvar=getenv("EDITOR"); printf("The editor environment variable is set to %s\n",myenvvar);} |
將上面的代碼儲存到檔案 myenv.c 中,然後發出以下命令進行編譯:
現在,目錄中將有一個可執行程式,它在運行時將列印 EDITOR 環境變數的值(如果有值的話)。這是在我機器上運行時的情況:
$ ./myenvThe editor environment variable is set to (null) |
啊... 因為沒有將 EDITOR 環境變數設定成任何值,所以 C 程式得到一個Null 字元串。讓我們試著將它設定成特定值:
$ EDITOR=xemacs$ ./myenvThe editor environment variable is set to (null) |
雖然希望 myenv 列印值 "xemacs",但是因為還沒有匯出環境變數,所以它卻沒有很好地工作。這次讓它正確工作:
$ export EDITOR$ ./myenvThe editor environment variable is set to xemacs
現在,如您親眼所見:不匯出環境變數,另一個進程(在本例中是樣本 C 程式)就看不到環境變數。順便提一句,如果願意,可以在一行定義並匯出環境變數,如下所示:
這與兩行版本的效果相同。現在該示範如何使用 unset 來除去環境變數:
$ unset EDITOR$ ./myenvThe editor environment variable is set to (null)