bash

維基百科,自由的百科全書
前往: 導覽搜尋
Bash
Bash demo.png
展示部分特性的Bash與sh會話截圖sessions demonstrating some features
原作者 布賴恩·福克斯
初始版本 1989年6月7日;25年前 (1989-06-07)
穩定版本 4.3 (2014年2月27日;4個月前 (2014-02-27)) [±][1]
開發狀態 Active
程式語言 C
作業系統 跨平台
平台 GNU
語言 英語,多語言(gettext
型別 Unix shell
授權條款 GNU通用公眾授權條款第3版+[2]
網站 www.gnu.org/software/bash/

bashUnix shell的一種,在1987年由布萊恩·福克斯為了GNU計劃而編寫。1989年釋出第一個正式版本,原先是計劃用在GNU作業系統上,但能執行於大多數類Unix系統的作業系統之上,包括LinuxMac OS X v10.4都將它作為預設shell。它也被移植到Microsoft Windows上的CygwinMinGW,或是可以在MS-DOS上使用的DJGPP計畫。在Novell NetWareAndriod在上也有移植。1990年後,Chet Ramey成為了主要的維護者。

Bourne shell的後繼相容版本與開放原始碼版本,它的名稱來自Bourne shell(sh)的一個雙關語(Bourne again / born again):Bourne-Again SHell。

語法與特性[編輯]

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 shellZ 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 Enter符
\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,bash在啟動後進入posix模式,它會儘可能模仿sh歷史版本的啟動行為,以便遵守POSIX標準。用sh名字呼叫的非互動shell不會去讀取其他啟動指令碼,--rcfile參數無效。

當bash以POSIX模式啟動時(例如帶有--posix參數)它使用POSIX標準來讀取啟動檔案。在此模式下,互動shells擴充功能變數ENV,從以此為檔案名的檔案中讀取命令並執行。

bash會探測自己是不是被遠端shell守護程式執行(通常是rshd)。如果是,它會讀取並執行~/.bashrc中的命令。但是rshd一般不會用rc相關參數呼叫shell,也不會允許指定這些參數。

註腳[編輯]

  1. ^ Ramey, Chet. Bash-4.3 available for FTP. info-gnu mailing list. 2014-02-27 [2014-02-27]. 
  2. ^ GNU Project. README file. "Bash is free software, distributed under the terms of the [GNU] General Public License as published by the Free Software Foundation, version 3 of the License (or any later version)." 

外部連結[編輯]