概念
Bash (GNU Bourne-Again Shell) 是許多Linux發行版的默認Shell 。事實上,還有許多傳統UNIX上用的Shell,例如tcsh、csh、ash、bsh、ksh等等,Shell Script大致都類同,當您學會一種Shell以後,其它的Shell會很快就上手,大多數的時候,一個Shell Script通常可以在很多種Shell上使用。
bash是大多數Linux系統以及Mac OS X默認的shell,它能運行於大多數類Unix風格的作業系統之上,甚至被移植到了Microsoft Windows上的Cygwin系統中,以實現Windows的POSIX虛擬接口。此外,它也被DJGPP項目移植到了MS-DOS上。
bash的命令語法是Bourne shell命令語法的超集。數量龐大的Bourne shell腳本大多不經修改即可以在bash中執行,只有使用了Bourne的特殊變數或內置命令的腳本才需要修改。 bash的命令語法很多來自Korn shell (ksh) 和 C shell (csh), 例如命令行編輯,命令歷史,目錄棧,$RANDOM 和 $PPID 變數,以及POSIX的命令置換語法: $(...)。作為一個互動式的shell,按下TAB鍵即可自動補全已部分輸入的程式名、檔案名稱、變數名等等。
環境變數
在 bash 和幾乎所有其它 shell中,用戶可以定義環境變數,這些環境變數在以 ASCII字元串存儲。環境變數的最便利之處在於:它們是 UNIX進程模型的標準部分。這意味著:環境變數不僅由 shell腳本獨用,而且還可以由編譯過的標準程式使用。當在 bash中“導出”環境變數時,以後運行的任何程式,不管是不是 shell腳本,都可以讀取設定。一個很好的例子是 vipw 命令,它通常允許 root用戶編輯系統口令檔案。通過將 EDITOR環境變數設定成喜愛的文本編輯器名稱,可以配置vipw,使其使用該編輯器,而不使用 vi,如果習慣於 xemacs 而確實不喜歡vi,那么這是很便利的。
在 bash 中定義環境變數的標準方法是:
$ myvar="This is my environment variable!"
以上命令定義了一個名為 "myvar" 的環境變數,並包含字元串 "This ismy environment variable!"。以上有幾點注意事項:第一,在等號 "="的兩邊沒有空格,任何空格將導致錯誤(試一下看看)。第二個件要注意的事是:雖然在定義一個字時可以省略引號,但是當定義的環境變數值多於一個字時(包含空格或製表鍵),引號是必須的。
注意:有關如何在 bash 中使用引號的非常詳盡的信息,請參閱 bash幫助頁面中的“引用”一節。特殊字元序列由其它值“擴展”(替換)確實使bash 中字元串的處理變得複雜。本系列將只講述最常用的引用功能。
第三,雖然通常可以用雙引號來替代單引號,但在上例中,這樣做會導致錯誤。為什麼呢?因為使用單引號禁用了稱為擴展的bash 特性,其中,特殊字元和字元系列由值替換。例如,"!"字元是歷史擴展字元,bash通常將其替換為前面輸入的命令。(本系列文章中將不講述歷史擴展,因為它在bash 編程中不常用。有關歷史擴展的詳細信息,請參閱 bash幫助頁中的“歷史擴展”一節。)儘管這個類似於宏的功能很便利,但我們現在只想在環境變數後面加上一個簡單的感嘆號,而不是宏。
現在,讓我們看一下如何實際使用環境變數。這有一個例子:
$ echo $myvarThis is my environment variable!
通過在環境變數的前面加上一個 $,可以使 bash 用 myvar的值替換它。這在 bash術語中叫做“變數擴展”。但是,這樣做將怎樣:
$ echo foo$myvarbar
我們希望回顯 "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中,然後發出以下命令進行編譯:
$ gcc myenv.c -o myenv
現在,目錄中將有一個可執行程式,它在運行時將列印 EDITOR環境變數的值(如果有值的話)。這是在我機器上運行時的情況:
$ ./myenvThe editor environment variable is set to (null)
啊... 因為沒有將 EDITOR 環境變數設定成任何值,所以 C程式得到一個空字元串。讓我們試著將它設定成特定值:
$ EDITOR=xemacs$ ./myenvThe editor environment variable is set to (null)
雖然希望 myenv 列印值"xemacs",但是因為還沒有導出環境變數,所以它卻沒有很好地工作。這次讓它正確工作:
$ export EDITOR$ ./myenvThe editor environment variable is set to xemacs
現在,如您親眼所見:不導出環境變數,另一個進程(在本例中是示例 C程式)就看不到環境變數。順便提一句,如果願意,可以在一行定義並導出環境變數,如下所示:
$ export EDITOR=xemacs
這與兩行版本的效果相同。現在該演示如何使用 unset來除去環境變數:
$ unset EDITOR$ ./myenvThe editor environment variable is set to (null)
參數說明
-c字元串
若用-c參數,則bash從字元串中讀入命令,如果字元串後還有變數就被設定為從$0開始的位置參數。
-i
若用-i參數,則bash是互動的。
-s
若用-s參數,則bash從標準輸入中讀入命令(在執行完-c帶的命令之後。)直到輸入exit。
-
單一的號表明參數執行完畢,並且禁止此後所跟參數,後面的所有變數都被看作是檔案名稱。
-norc
如果bash是互動的,則不執行個人初始化檔案:-/.bashrc,如果bash作為sh來運行,這個參數預設是關閉的。
-noprofile
不執行系統範圍的啟動檔案/etc/profile也不執行個人的啟動檔案-/.bash_profile,-/.bash_login或-/.profile,預設情況下,bash作為登錄的shell時以這些檔案作為啟動檔案。
--refile檔案名稱
如果bash是互動的,則以此檔案作為bash的啟動檔案。替代-/.bashrc。
-version
在bash開始時顯示此bash的版本號。
-quiet
不顯示版本號和其他信息,這是預設值。
-login
激活bash,偽裝為登錄shell。
-nobraceexpansion
不執行大括弧擴展。
-nolineediting
在互動狀態下不使用GNU的readline庫去讀取命令。即取消了命令行編輯功能。
-posix
改變bash的行為,使其符合Posix 1003.2規定的標準。
外界評價
Linux之父Linus對BASH的描述:
“我下載了一個叫Bourne Shell的外殼程式。它是UNIX的初始外殼程式之一,可以從網際網路上免費下載,名字來源於一個難聽的雙關語。編寫該外殼程式的傢伙名叫波恩(英文中的“忍受”或“出生”之意――譯註),所以這個程式就叫做“Bourne-Again-Shell”(“再次忍受或再次降生外殼程式”――譯註),或一般被稱為BASH(bash的英文意為“重擊”――譯註)。”
BASH的正確縮寫:
BASH = GNU Bourne-Again Shell,BASH 是 GNU 組織開發和推廣的一個項目。
BASH的作者和產生:
Bourne shell 的作者是 Steven Bourne,它是 UNIX 最初使用的 Shell 並且在每種 UNIX 上都可以使用。
而BASH 與 Bourne shell 完全向後兼容,是Bourne shell的擴展。
雙關語的經典之處:.
[1]作者名叫Steven Bourne,“bourne”與“born”的發音相近,而born有“出生”和“忍受”的含義。
[2]Bourne-Again字面意思代表了它是“Bourne shell”l的一種擴展,而暗示“borne-again”、“born-again”則有“重生”和“再次忍受”的意思。(我想作者應該更喜歡“重生”)
[3]它的簡寫“bash”的意思是“重擊”,暗示它的出現是一次強有力的重擊。
基本語法
· 最簡單的例子 —— Hello World!
· 關於輸入、輸出和錯誤輸出
· BASH 中對變數的規定(與 C 語言的異同)
· BASH 中的基本流程控制語法
· 函式的使用