歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> SHELL編程

Bourne again shell (bash) 基本編程

  已經在運行它  如果查看一下,可能會發現:您現在正在運行 bash。因為 bash 是標准 Linux shell,並用於各種目的,所以,即使更改了缺省 shell,bash 可能仍在系統中某處運行。因為 bash 已在運行,以後運行的任何 bash 腳本都天生是有效利用內存的,因為它們與任何已運行的 bash 進程共享內存。如果正在運行的工具可以勝任工作,並且做得很好,為什麼還要裝入一個 500K 的解釋器?    已經在使用它  不僅在運行 bash,實際上,您每天還在與 bash 打交道。它總在那裡,因此學習如何最大限度使用它是有意義的。這樣做將使您的 bash 經驗更有趣和有生產力。但是為什麼要學習 bash 編程?很簡單,因為您已在考慮如何運行命令、CPing 文件以及管道化和重定向輸出。為什麼不學習一種語言,以便使用和利用那些已熟悉和喜愛的強大省時的概念?命令 shell 開啟了 UNIX 系統的潛能,而 bash 正是這個 Linux shell。它是您和機器之間的高級紐帶。增長 bash 知識吧,這將自動提高您在 Linux 和 UNIX 中的生產力 -- 就那麼簡單。    Bash 困惑  以錯誤方式學習 bash 令人十分困惑。許多新手輸入 "man bash" 來查看 bash 幫助頁,但只得到非常簡單和技術方面的 shell 功能性描述。還有人輸入 "info bash"(來查看 GNU 信息文檔),只能得到重新顯示的幫助頁,或者(如果幸運)略為友好的信息文檔。    盡管這可能使初學者有些失望,但標准 bash 文檔無法滿足所有人的要求,它只適合那些已大體熟悉 shell 編程的人。幫助頁中確實有很多極好的技術信息,但對初學者的幫助卻有限。    這就是本系列的目的所在。在本系列中,我將講述如何實際使用 bash 編程概念,以便編寫自己的腳本。與技術描述不同,我將以簡單的語言為您解釋,使您不僅知道事情做什麼,還知道應在何時使用。在此三部分系列末尾,您將可以自己編寫復雜的 bash 腳本,並可以自如地使用 bash 以及通過閱讀(和理解)標准 bash 文檔來補充知識。讓我們開始吧。    環境變量  在 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 environment variable!"。以上有幾點注意事項:第一,在等號 "=" 的兩邊沒有空格,任何空格將導致錯誤(試一下看看)。第二個件要注意的事是:雖然在定義一個字時可以省略引號,但是當定義的環境變量值多於一個字時(包含空格或制表鍵),引號是必須的。    引用細節  有關如何在 bash 中使用引號的非常詳盡的信息,請參閱 bash 幫助頁面中的“引用”一節。特殊字符序列由其它值“擴展”(替換)確實使 bash 中字符串的處理變得復雜。本系列將只講述最常用的引用功能。     第三,雖然通常可以用雙引號來替代單引號,但在上例中,這樣做會導致錯誤。為什麼呢?因為使用單引號禁用了稱為擴展的 bash 特性,其中,特殊字符和字符系列由值替換。例如,"!" 字符是歷史擴展字符,bash 通常將其替換為前面輸入的命令。(本系列文章中將不講述歷史擴展,因為它在 bash 編程中不常用。有關歷史擴展的詳細信息,請參閱 bash 幫助頁中的“歷史擴展”一節。)盡管這個類似於宏的功能很便利,但我們現在只想在環境變量後面加上一個簡單的感歎號,而不是宏。    現在,讓我們看一下如何實際使用環境變量。這有一個例子:    $ echo $myvar  This is my environment variable!     通過在環境變量的前面加上一個 $,可以使 bash 用 myvar 的值替換它。這在 bash 術語中叫做“變量擴展”。但是,這樣做將怎樣:    $ echo foo$myvarbar  foo     我們希望回顯 "fooThis is my environment variable!bar",但卻不是這樣。錯在哪裡?簡單地說,bash 變量擴展設施陷入了困惑。它無法識別要擴展哪一個變量:$m、$my、$myvar 、$myvarbar 等等。如何更明確清楚地告述 bash 引用哪一個變量?試一下這個:    $ echo foo${myvar}bar  fooThis is my environment variable!bar     如您所見,當環境變量沒有與周圍文本明顯分開時,可以用花括號將它括起。雖然 $myvar 可以更快輸入,並且在大多數情況下正確工作,但 ${myvar} 卻能在幾乎所有情況下正確通過語法分析。除此之外,二者相同,將在本系列的余下部分看到變量擴展的兩種形式。請記住:當環境變量沒有用空白(空格或制表鍵)與周圍文本分開時,請使用更明確的花括號形式。    回想一下,我們還提到過可以“導出”變量。當導出環境變量時,它可以自動地由以後運行的任何腳本或可執行程序環境使用。shell 腳本可以使用 shell 的內置環境變量支持“到達”環境變量,而 C 程序可以使用 getenv() 函數調用。這裡有一些 C 代碼示例,輸入並編譯它們 -- 它將幫助我們從 C 的角度理解環境變量:    myvar.c -- 樣本環境變量 C 程序    #include   #include     int main(void) {   char *myenvvar=getenv("EDITOR");   printf("The editor environment variable is set to %s",myenvvar);  }     將上面的代碼保存到文件 myenv.c 中,然後發出以下命令進行編譯:    $ gcc myenv.c -o myenv     現在,目錄中將有一個可執行程序,它在運行時將打印 EDITOR 環境變量的值(如果有值的話)。這是在我機器上運行時的情況:    $ ./myenv  The editor environment variable is set to (null)     啊... 因為沒有將 EDITOR 環境變量設置成任何值,所以 C 程序得到一個空字符串。讓我們試著將它設置成特定值:    $ EDITOR=xemacs  $ ./myenv  The editor environment variable is set to (null)     雖然希望 myenv 打印值 "xemacs",但是因為還沒有導出環境變量,所以它卻沒有很好地工作。這次讓它正確工作:    $ eXPort EDITOR  $ ./myenv  The editor environment variable is set to xemacs     現在,如您親眼所見:不導出環境變量,另一個進程(在本例中是示例 C 程序)就看不到環境變量。順便提一句,如果願意,可以在一行定義並導出環境變量,如下所示:    $ export EDITOR=xemacs     這與兩行版本的效果相同。現在該演示如何使用 unset 來除去環境變量:    $ unset EDITOR  $ ./myenv  The editor environment variable is set to (null)     dirname 和 basename  請注意:dirname 和 basename 不是磁盤上的文件或目錄,它們只是字符串操作命令。     截斷字符串概述  截斷字符串是將初始字符串截斷成較小的獨立塊,它是一般 shell 腳本每天執行的任務之一。很多時候,shell 腳本需要采用全限定路徑,並找到結束的文件或目錄。雖然可以用 bash 編碼實現(而且有趣),但標准 basename UNIX 可執行程序可以極好地完成此工作:    $ basename /usr/local/share/doc/foo/foo.txt  foo.txt  $ basename /usr/home/drobbins  drobbins     Basename 是一個截斷字符串的極簡便工具。它的相關命令 dirname 返回 basename 丟棄的“另”一部分路徑。    $ dirname /usr/local/share/doc/foo/foo.txt  /usr/local/share/doc/foo  $ dirname /usr/home/drobbins/  /usr/home     命令替換  需要知道一個簡便操作:如何創建一個包含可執行命令結果的環境變量。這很容易:      $ MYDIR=`dirname /usr/local/share/doc/foo/foo.txt`  $ echo $MYDIR  /usr/local/share/doc/foo     上面所做的稱為“命令替換”。此例中有幾點需要指出。在第一行,簡單地將要執行的命令以 反引號括起。那不是標准的單引號,而是鍵盤中通常位於 Tab 鍵之上的單引號。可以用 bash 備用命令替換語法來做同樣的事:    $ MYDIR=$(dirname /usr/local/share/doc/foo/foo.txt)  $ echo $MYDIR  /usr/local/share/doc/foo     如您所見,bash 提供多種方法來執行完全一樣的操作。使用命令替換可以將任何命令或命令管道放在 ` ` 或 $( ) 之間,並將其分配給環境變量。真方便!下面是一個例子,演示如何在命令替換中使用管道:    MYFILES=$(ls /etc grep pa)  bash-2.03$ echo $MYFILES  pam.d passwd     象專業人員那樣截斷字符串  盡管 basename 和 dirname 是很好的工具,但有時可能需要執行更高級的字符串“截斷”,而不只是標准的路徑名操作。當需要更強的說服力時,可以利用 bash 內置的變量擴展功能。已經使用了類似於 ${MYVAR} 的標




Copyright © Linux教程網 All Rights Reserved