Bash


Bash (简体)

Free Web Hosting with Website Builder

GNU Bourne-Again Shell


bash會話的一個截屏
開發 Chet Ramey
最近版本 3.2.39 / 2008年4月30日
作業系統 多系統
類型 Unix shell
許可協議 GNU General Public License
網站 [1]
檢視  討論  編輯  歷史

bash 是一個為GNU項目編寫的Unix shell。它的名字是一系列縮寫:Bourne-Again SHell — 這是關於Bourne shell(sh)的一個雙關語 (Bourne again / born again)。Bourne shell是一個早期的重要shell,由Stephen Bourne在1978年前後編寫,並同Version 7 Unix一起發布。bash則在1987年由Brian Fox創造。在1990年,Chet Ramey成為了主要的維護者。

bash是大多數Linux系統以及Mac OS X v10.4預設的shell,它能運行於大多數Unix風格的作業系統之上,甚至被移植到了Microsoft Windows上的Cygwin系統中,以實現windows的POSIX虛擬介面。此外,它也被DJGPP項目移植到了MS-DOS上。

目錄

語法與特性

bash的命令語法是Bourne shell命令語法的超集。數量龐大的Bourne shell腳本大多不經修改即可以在bash中執行,只有那些引用了Bourne特殊變數或使用了Bourne的內置命令的腳本才需要修改。 bash的命令語法很多來自Korn shell (ksh) 和 C shell (csh), 例如命令行編輯,命令歷史,目錄棧,$RANDOM$PPID 變數,以及POSIX的命令置換語法: $(...)。作為一個互動式的shell,按下TAB鍵即可自動補全已部分輸入的程序名,文件名,變數名等等。

bash的語法針對Bourne shell的不足做了很多擴展。其中的一些列舉在這裡。

使用整數

與Bourne shell不同的是bash不用另外生成進程即能進行整數運算。bash 使用((...)) 命令和 $[...] 變數語法來達到這個目的:

VAR=55             # 将整数 55 赋值给变量 VAR
((VAR = VAR + 1))  # 变量 VAR 加 1。 注意这里没有 '$' 
((++VAR))          # 另一种方法给 VAR 加 1。 使用C语言风格的前缀自增
((VAR++))          # 另一种方法给 VAR 加 1。 使用C语言风格的后缀自增
echo $[VAR * 22]   # VAR 乘以 22 并将结果送入命令
echo $((VAR * 22)) # 同上

((...)) 命令可以用於條件語句,因為它的退出狀態是0或者非0(大多數情況下是1),可以用於是與非的條件判斷:

if ((VAR == Y * 3 + X * 2))
then
        echo Yes
fi

((Z > 23)) && echo Yes

((...)) 命令支持下列比較操作符:'==', '!=', '>', '<', '>=', 和 '<='。

bash不能在自身進程內進行浮點數運算。當前有這個能力的unix shell只有Korn shell 和 Z shell.

輸入/輸出重定向

bash擁有傳統Bourne shell 缺乏的I/O重定向語法。bash可以同時重定向標準輸出和標準錯誤,這需要使用下面的語法:

command &> file

這比等價的Bourne shell語法 "command > file 2>&1" 來的簡單。2.05b版本以後,bash可以用下列語法重定向標準輸入至字元串(稱為here string):

command <<< "string to be read as standard input"

如果字元串包括空格就需要用引號包裹字元串。

例子: 重定向標準輸出至文件,寫數據,關閉文件,重置標準輸出。

# 生成标准输出(文件描述符1)的拷贝文件描述符6
exec 6>&1
# 打开文件"test.data"以供写入
exec 1>test.data
# 产生一些内容
echo "data:data:data"
# 关闭文件 "test.data"
exec 1>&-
# 使标准输出指向FD 6 (重置标准输出)
exec 1>&6
# 关闭 FD6
exec 6>&-

打開及關閉文件

# 打开文件 test.data 以供读取
exec 6<test.data
# 读文件直到文件尾
while read -u 6 dta
do
  echo "$dta" 
done
# 关闭文件 test.data
exec 6<&-

抓取外部命令的輸出

 # 运行'find'并且将结果存于 VAR
 # 搜索以"h"结尾的文件名
 VAR=$(find . -name "*h")

進程內的正則表達式

bash 3.0 支持進程內的正則表達式,使用下面的語法 :

[[ string =~ regex ]]

正則表達式語法同regex(7) man page 所描述的一致。正則表達式匹配字元串時上述命令的退出狀態為0,不匹配為1。正則表達式中用圓括號括起的子表達式可以訪問shell變數 BASH_REMATCH ,如下:

if [[ abcfoobarbletch =~ 'foo(bar)bl(.*)' ]]
then
        echo The regex matches!
        echo $BASH_REMATCH      -- outputs: foobarbletch
        echo ${BASH_REMATCH[1]} -- outputs: bar
        echo ${BASH_REMATCH[2]} -- outputs: etch
fi

使用這個語法的性能要比生成一個新的進程來運行 grep 命令優越,因為正則表達式匹配在bash進程內完成。如果正則表達式或者字元串包括空格或者shell 關鍵字,(諸如 '*' 或者 '?'),就需要用引號包裹。

轉義字元

$'string'形式的字元串會被特殊處理。字元串會被展開成 string,並像C語言那樣將反斜杠及緊跟的字元進行替換。反斜杠轉義序列的轉換方式如下:

轉義字元
轉義字元 擴展成 ...
\a 響鈴符
\b 退格符
\e ANSI轉義符,等價于\033
\f 饋頁符
\n 換行符
\r 回車符
\t 水平製表符
\v 垂直製表符
\\ 反斜杠
\' 單引號
\nnn 十進位值為nnn的8-bit字元(1-3位)
\xHH 十六進位值為HH的8-bit字元(1或2位)
\cx control-X 字元

擴展後的結果將被單引號包裹,就好像美元符號一直就不存在一樣。

雙引號包裹的字元串前若有一個美元符號 ($"...") 將會使得字元串被翻譯成符合當前locale的語言。如果當前locale是 C 或者 POSIX,美元符號會被忽略。如果字元串被翻譯並替換,替換後的字元串仍被雙引號包裹。

啟動腳本

bash啟動的時候會運行各種不同的腳本。

當bash作為一個登錄的交互shell被調用,或者作為非交互shell但帶有--login參數被調用時,它首先讀入並執行文件/etc/profile。然後它會依次尋找 ~/.bash_profile~/.bash_login,和 ~/.profile,讀入並執行第一個存在且可讀的文件。 --noprofile 參數可以阻止bash啟動時的這種行為。

當一個登錄shell退出時,bash讀取並執行 ~/.bash_logout 文件,如果此文件存在。

當一個交互的非登錄shell啟動後,bash讀取並執行 ~/.bashrc 文件。這個行為可以用 --norc 參數阻止。--rcfile file 參數強制 bash 讀取並執行指定的 file 而不是預設的 ~/.bashrc

如果用 sh 來調用bash,它會盡可能模仿sh歷史版本的啟動行為,以便遵守POSIX標準。當bash作為登錄的交互shell被調用時,或者作為非交互的但帶有--login參數被調用時,它首先依次讀入並執行/etc/profile~/.profile--noprofile 參數可以阻止這行為。當以 sh 的名字作為交互shell被調用時,bash 尋找變數 ENV,擴展它的值,並使用擴展的值作為要讀取運行的文件名。以名字 sh 被調用的shell不會去尋找並讀取其他啟動腳本, --rcfile 參數無效。用 sh 名字調用的非交互shell不會去讀取其他啟動腳本。當用 sh調用bash時,bash在啟動後進入posix模式。

當bash以 POSIX 模式啟動時(例如帶有 --posix 參數)它使用POSIX標準來讀取啟動文件。在此模式下,交互 shells 擴展變數 ENV ,從以此為文件名的文件中讀取命令並執行。bash不會讀取其他文件。

bash會探測自己是不是被遠程shell守護程序運行(通常是rshd)。如果是,它會讀取並執行 ~/.bashrc中的命令。如果是被sh調用,它就不會這麼做。 --norc 參數可以組織這行為,--rcfile 參數可以強制讀取另一個文件,但是 rshd 一般不會用這些參數調用shell,也不會允許這些參數可以被指定。

外部連結







Why are we here?
All text is available under the terms of the GNU Free Documentation License
This page is cache of Wikipedia. History