跳至內容

Bash

出自Taiwan Tongues 台語維基
於 2025年8月22日 (五) 12:39 由 TaiwanTonguesApiRobot留言 | 貢獻 所做的修訂 (從 JSON 檔案批量匯入)

(差異) ←上個修訂 | 已批准修訂 (差異) | 最新修訂 (差異) | 下個修訂→ (差異)

Bash,Unix shell 的一種,佇一九八七年由布萊恩 ・ 福克斯為著欲 GNU 計畫來編寫。一九八九年釋出頭一个正式的版本,原先是咧計畫用佇咧 GNU 作業系統上,但是當執行大多數類 Unix 系統的作業系統之上,包括講 Linux 佮 Mac OS X v 十寢四起到 macOS Mojave 攏共伊做預設 shell,而自 macOS Catalina,預設 Shell 以 zsh 取代。

Bash 是 Bourne shell 的後繼相容版本佮開放原始碼版本,伊的名稱來自 Bourne shell(sh)的一个雙關語(_ Bourne again _ / born again):Bourne-AgainSHell。

Bash 是一个命令處理器,通常執行佇文字窗口內底,並會當執行使用者直接輸入的命令。Bash 猶閣會當對檔案內底讀號命令,這款的檔案叫做指令碼。佮其他 Unix shell 仝款,伊支援檔名替換(萬用字元匹配)、 管道、here 文件、命令替換、變數,猶佮條件判斷佮迴箍遍歷的結構控制語句。包括關鍵字、語法在內的基本特性全部攏是 sh 借鑑過來的。其他的特性,譬如講歷史命令,是對 csh 和 ksh 借鑑來爾。總的來講,Bash 雖然是一个滿足 POSIX 規範的 shell,毋過有足濟擴充。

一个叫做 Shellshock 的安全漏洞佇二空一四年九月初予人發現,緊氣致使網路頂懸的一系列攻擊。這个空會當追溯到一九八九年釋出的一孵空三版本。

歷史

因為理察 ・ 斯托曼對進前有一个開發者的進度不滿,布萊恩 ・ 福克斯一九八八年一月十號開始開發 Bash。斯托曼和自由軟體基金會望著一个會當執行已經有的 shell 指令碼的自由軟體。𪜶共這看做是建成一个是因為 BSD 和 GNU 的完全自由的作業系統戰略的重要部份。這是𪜶家己注資的幾个案之一。福克斯作為自由軟體基金會的雇員承擔這項工課。一九八九年六月初八,福克斯釋出 Bash 的 beta 版本,版本號做 . 九十九。佇福克斯離開佇一九九二年中期到一九九四年中期的某一个時陣離開自由軟體基金會進前,伊一直擔任 Bash 的主要維護者。了後,伊的工課被傳達予另外一个早期貢獻者,切特 ・ 雷米(Chet Ramey)。

自彼陣仔起,佇咧 Linux 使用者當中 sh 佇咧足大度上成做上流行的 shell,並成做真濟 Linux 發行版預設的互動式 shell(猶毋過 Almquist shell 可能是預設的指令碼 shell)。 佇蘋果公司的 OS X 作業系統上也是按呢。Bash 嘛予徙栽去到 Microsoft Windows(通過 Cygwin 和 MinGW)。 通過 DJGPP 專案,Bash 去予徙栽到矣 DOS。通過誠濟終端類比軟體,Bash 予徙栽到 Novell NetWare 和 Android。微軟佇二空一六年的 Build 大會頂宣佈,Windows 真正十添一个 Linux 子系統,完全支援 Bash 佮其他 Ubuntu 下底的這位程式。

二空一四年九月二四,Stephane Chazelas,一个工作佇英國,拍拚咧 Unix / Linux 佮網路通信方面的專家,發現 Bash 的一个安全漏洞。這个漏洞去予人號做 Shellshock,並且予人分配編號 CVE 鋪二千空一十四抹六千兩百七十一、CVE 鋪二千空一十四陽六千兩百七十七、CVE 鋪二千空一十四陽七千一百六十九。這个漏洞足嚴重的,因為使用 Bash 的 CGI 指令碼會變較脆弱,予𪜶攻擊者會當執行任意的代碼。這个漏洞佮 Bash 通過環境變數共函式定義傳達予 shell 子行程的方式有關。

語法佮特性

bash 伊的命令語法是 Bourne shell 命令語法的超集。數量遐爾大的 Bourne shell 指令碼大部份攏無經修改即會當講 bash 中執行,只有遐的參照矣 Bourne 特殊變數抑是使用 Bourne 內底建命令的指令碼才需要修改。bash 伊的命令語法足濟來自 Korn shell(ksh)和 C shell(csh), 譬如講命令列編輯,命令歷史,kha-tá-lok-guh 棧,$ RANDOM 和 $ PPID 變數,以及 POSIX 的命令置換語法:$ ( . . . )。做為一个互動式的 shell,揤落去 TAB 鍵就會當自動補全已經部份輸入的程式名,檔名,變數名等等。

使用'function'關鍵字的時陣,Bash 的函式聲明佮 Bourne / Korn / POSIX 指令碼無相容(Korn shell 有仝款的問題)。 猶毋過 Bash 嘛接受 Bourne / Korn / POSIX 的函式聲明語法。因為足濟無仝款,Bash 指令碼蓋少有法度佇 Bourne 抑是 Korn 直譯器中執行,除非編寫指令碼時刁工保持相容性。毋過,隨著 Linux 的普及,這種方式當變甲那來那少。猶毋過佇 POSIX 模式下,Bash 更加符合 POSIX。

bash 的語法針對 Bourne shell 的不足做了足濟擴充。內底的一寡列舉佇咧遮。

花括號擴充

花括號擴充是一个對 C shell 借鑑來的特性,伊產生一系列指定的字串(按照原底對左到右的順序)。 遮的字串無需要是已經存在的檔案。

花括號擴充無應該被用佇可徙栽 shell 指令碼中,因為乎 Bourne shell 產生的後果無仝。

當花括號擴充佮萬用字元做伙使用的時陣,花括號擴充頭一改先予人解破,然後正常解破萬用字元。所以,會當用這種方法接著進前 kha-tá-lok-guh 的一系列 JPEG 和 PEG 檔案。

除了列舉備選項,猶閣會用得「. .」佇咧花括號擴充中指定字元或者是數字範圍。比較新的 Bash 版本接受一个整數作為第三个參數,指定增量。

當花括號擴充佮變數擴充做伙使用的時陣,變數擴充解析佇花括號擴充了後。有當時有必要使用內起的 ` eval ` 函式

用整數

佮 Bourne shell 無仝的是 bash 毋免另外生成行程就會當進行整數運算。bash 使用 ( ( . . . ) ) 號令和 $ [. . .] 變數語法來達到這个目的:

( ( . . . ) ) 命令會當用佇條件語句,因為伊的登出狀態是零抑是非零(大多數的情況下是一), 會當用於是佮非的條件判斷:

( ( . . . ) ) 命令支援下列較運算子:'==','!=','>','<','>=',和'<='。

bash 袂當佇家己行程內底做浮點數運算。當前有這个能力的 unix shell 只有 Korn shell 和 Z shell。

輸入輸出重新導向

bash 有傳統 Bourne shell 欠缺的 I / O 重新導向語法。bash 會當同時重新導向標準輸出佮標準錯誤,這需要使用下跤的語法:

這比等價的 Bourne shell 語法 " command > file 二 > & 一 " 來的簡單。二孵空五 b 版本以後,bash 會當用下列語法重新導向標準輸入至字串(這號做 here string):

若字串包括空格就需要用引號包裹字串。

: 重新導向標準輸出至檔案,寫資料,關檔案,重新設標準輸出。

拍開佮關閉檔案掠外部命令的輸出

行程內底的正規表示式

bash 三更零支援行程內底的正規表示式,用下跤的語法:

正規表示式語法仝 regex ( 七 ) man page 所講的一致。正規表示式匹配字串時上述命令的登出狀態做零,不匹配為一。正規表示式中用圓括號括起的子表達式會當存取 shell 變數 BASH \ _ REMATCH,如下:

使用這个語法的效能愛比生做一个新的行程來執行 grep 命令優越,因為正規表示式匹配佇 bash 行程內底完成。若是正規表示式或者是字串包括空格或者是 shell 關鍵字,(諸如'\ *'抑是講'?'), 就需要用引號包裹。Bash 四開始的版本已經無需要按呢做矣。

跳脫字元

$'string'形式的字串會予特殊處理。字串會予人展開做 string,並像 C 語言彼款欲反斜槓佮絚綴的字元進行替換。反斜槓跳脫序列的轉換方式如下:

擴充了後的結果將被單引號包裹,就袂輸敢若美元符號一直就不存在仝款。

雙引號包裹的字串前若有一个美金符號($ " . . . ")將會予字串去予人翻做符合當前 locale 的語言。若講當前 locale 是 C 抑是講 POSIX,美金符號會予人無注意。若字串予人翻譯做伙換,替換後的字串猶原被雙引號包裹。

關聯陣列

Bash 四配零開始支援關聯陣列,通過類似 AWK 的方式,對較濟維陣列提供了偽支援。

移植性

搧叫 Bash 時指定 `--posix ` 抑是講佇咧講令碼中聲明 ` set-o posix `,有法度予 Bash 強欲遵循 POSIX 一千空三石二標準。你若欲保證一个 Bash 指令碼的移植性,至少需要考慮著 Bourne shell,即 Bash 取代的 shell。Bash 有一寡傳統的 Bourne shell 所無的特性,包括以下遮的:

  • 某一寡擴充的呼叫選項
  • 命令替換(即 ` $ ( ) `)(就算講這是 POSIX 一千空三石二標準的一部份)
  • 花括號擴充
  • 某一寡陣列操作、關聯陣列
  • 擴充的雙層方括號判斷語句
  • 某一寡字串生操作
  • 行程替換
  • 正規表示式匹配符
  • Bash 特別有的內建工具
  • 協行程

鍵盤快速鍵

Bash 預設使用 Emacs 的快速鍵,會當通過 ` set-o vi ` 予伊使用 Vi 的快速鍵

行程管理

Bash 有兩種執行命令的模式:批次處理模式、併發模式。

批次處理模式

愛以批次處理模式執行命令(即照順序), 著愛用 ` ; ` 分隔,比如講下跤:

佇這个例中,當 ` command 一 ` 執行煞畢,即執行 ` command 二 `。

併發模式

使 ` command 一 ` 背景執行,是單獨佇咧結尾的所在使用 ` & `,比如講下跤:

愛並行執行兩个命令,𪜶著愛用 ` & ` 分隔,比如講下跤:

佇這个情形下,` command 一 ` 佇後台執行(通過 ` & `), 對咧而且隨欲控制轉來到 shell,以執行 ` command 二 `。

通過 ` Control ` + ` Z ` 會當共當前行程掛起來(囥佇後台暫停執行), 會過 ` fg ` 命令恢復到前台,嘛通過 ` bg ` 將掛起的行程背景執行。

檢視行程狀態

所有的行程的情況,咱會當過 ` jobs ` 命令檢視,包含當咧背景執行佮停止矣的。

頂例的輸出結果中間,中括號包圍的數字(如:"[一] " 和 " [二] ")為 job 的 ID 號。加號 ( + ) 用佇指定 ` fg ` 和 ` bg ` 命令的預設物件 job。減號 (-) 用佇指定,若當前的預設物件 job 登出了後,後一个預設物件 job 是啥人。" Running " 和 " Stopped " 表示行程狀態。最後一个欄位做命令。


總結:

  • 一般的命令佇前台執行(` fg `), 執行了後,控制轉來予使用者。
  • 佇咧命令後壁加上 ` & `,伊會執行佇後台執行(` bg `), 並共特殊的環境變數 ` $ ! ` 設定做該任務的行程 ID。這陣 shell 會使並行執行其他的命令。
  • 後台程式試圖寫入資料到終端裝置的時陣(佮寫入標準輸出無仝)可能去予人窒起來矣。
  • shell 會當等待一个後台任務執行完成,干焦需要使用 ` wait ` 命令,加上行程 ID 或者是任務序號;嘛會使等待所有的後台任務,只需要使用無加參數的 ` wait `

啟動指令碼

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,也袂允准指定遮的參數。

Bash 佮 Bourne shell 和 csh 啟動指令碼的較

Bash 的特性是按 Bourne shell 和 csh 發展而來,所以一定程度允准仝款 Bourne shell 的啟動檔案分享,並且提供一寡 csh 使用者熟似的啟動特性。

設定會當繼承的環境變數

Bourne shell 登陸的時陣使用 ` ~ / . profile ` 來設定環境變數,遮的環境變數會當予子行程繼承。Bash 會當相容的方式來使用 ` ~ / . profile `,只需要佇咧 Bash 自有的指令碼中顯式執行下跤這途代碼。通過 ` ~ / . profile ` 中避免使用 Bash 特有的語法,就會當和 Bourne shell 保持相容性。

別名佮函式

閣較通用的函式和借鑑自 csh 的「別名 ( alias )」足大的程度上取代矣 Bourne shell 的別名 ( alias ) 和函式。毋過這兩个特性一般袂當對登入式 shell 對中繼承,佇這个登入式 shell 的子 shell 中,𪜶著愛予人重新定義。就算講有一个環境變數 ` ENV ` 會使予人用佇這个問題,猶毋過 csh 和 Bash 攏會當用子 shell 的啟動指令碼直接處理。佇咧 Bash 當中,` ~ / . bashrc ` 是互動式子 shell 啟動的時陣執行的指令碼。若是想欲佇登入式 shell 中使用 ` ~ / . bashrc ` 定義的函式,會當佇 ` ~ / . bash _ login ` 的環境變數後壁加上按呢一行:

登入佮登出的時執行的命令

上蓋起初登入的時陣,csh 執行 ` ~ / . login `,會當執行一寡干焦佇咧登入的時陣執行的操作,親像顯示系統負載、硬碟狀態、敢有收著新的郵件、佇紀錄檔中記錄登入時間,等咧。Bourne shell 會當佇 ` ~ / . profile ` 檔案中類比這種行為,但並無預先定義檔名。會當佇 ` ~ / . bash _ profile ` 檔案的環境變數設定佮函式定義的後壁添加按呢一行:

佮之類似,csh 猶閣有一个檔案 ` ~ / . logout `,這个檔案干焦佇咧登入式 shell 登出的時陣執行。Bash 佮之對應的檔案是 ` ~ / . bash _ logout `,並且無需要專門的設定。佇咧 Bourne shell 中,` trap ` 這內建工具會當實現類似的效果。

相容舊環境的 Bash 啟動指令碼範例

下跤這號 ` ~ / . bash _ profile ` 的框殼佮 Bourne shell 相容,並且為著 ` ~ / . bashrc ` 和 ` ~ / . bash _ login ` 提供類似 csh 的語意。` [-r _ 文件名 _ ] ` 測試指定檔案敢有存在,若是無存在,跳過 ` & & ` 後壁的部份

Bash 啟動指令碼佮作業系統有關係的問題

一寡仔 Unix 和 Linux 版本定佇咧 ` / etc ` 囥 Bash 系統級啟動指令碼。Bash 佇咧其標準的初初化過程當中執行𪜶,猶毋過其他啟動指令碼會當照無仝 Bash 啟動序列文件所述的順序來讀遮的檔案。root 使用者的檔案預設內容,閣有新使用者予建立時系統提供的預設檔案可能有問題。啟動 X Window 系統的啟動指令碼可能使用使用者的 Bash 啟動指令碼試看覓佇咧視窗管理員啟動進前設定使用者的環境變數。遮的問題定定會當通過使用 ` ~ / . xsession ` 抑是講 ` ~ / . xprofile ` 來讀取 ` ~ / . profile ` 來解決。

參見

  • Unix shell

註跤

外部連結

  • GNU Bash 頭頁
  • GNU Bash 佇咧 GNU 的首頁
  • bashdb,紮就是有除錯器的 Bash
  • Bash 入門指南(英文)
  • Bash 仝標準 unix shell 的無仝
  • Bash by example Bash 基礎編程