Arch manual pages

BASH(1) General Commands Manual BASH(1)

bash - GNU Bourne-Again SHell (GNU 命令解釋程序 “Bourne二世”)

bash [options] [file]

Bash is Copyright (C) 1989-2002 by the Free Software Foundation, Inc.

Bash 是一個與 sh 兼容的命令解釋程序,可以執行從標準輸入或者文件中讀取的命令。 Bash 也整合了 KornC Shell (kshcsh) 中的優秀特性。

Bash 的目標是成爲遵循 IEEE POSIX Shell and Tools specification (IEEE Working Group 1003.2,可移植操作系統規約: shell 和工具) 的實現。

除了在 set 內建命令的文檔中講述的單字符選項 (option) 之外,bash 在啓動時還解釋下列選項。

-c string
如果有 -c 選項,那麼命令將從 string 中讀取。如果 string 後面有參數 (argument),它們將用於給位置參數 (positional parameter,以 $0 起始) 賦值。
-i
如果有 -i 選項,shell 將交互地執行 ( interactive )。
-l
選項使得 bash 以類似登錄 shell (login shell) 的方式啓動 (參見下面的 啓動(INVOCATION) 章節)。
-r
如果有 -r 選項,shell 成爲受限的 ( restricted ) (參見下面的 受限的shell(RESTRICTED SHELL) 章節)。
-s
如果有 -s 選項,或者如果選項處理完以後,沒有參數剩餘,那麼命令將從標準輸入讀取。 這個選項允許在啓動一個交互 shell 時可以設置位置參數。
-D
向標準輸出打印一個以 $ 爲前導的,以雙引號引用的字符串列表。 這是在當前語言環境不是 CPOSIX 時,腳本中需要翻譯的字符串。 這個選項隱含了 -n 選項;不會執行命令。
[-+]O [shopt_option]
shopt_option 是一個 shopt 內建命令可接受的選項 (參見下面的 shell 內建命令(SHELL BUILTIN COMMANDS) 章節)。 如果有 shopt_option-O 將設置那個選項的取值; +O 取消它。 如果沒有給出 shopt_optionshopt 將在標準輸出上打印設爲允許的選項的名稱和值。 如果啓動選項是 +O,輸出將以一種可以重用爲輸入的格式顯示。
--
-- 標誌選項的結束,禁止其餘的選項處理。任何 -- 之後的參數將作爲文件名和參數對待。參數 - 與此等價。

Bash 也解釋一些多字節的選項。在命令行中,這些選項必須置於需要被識別的單字符參數之前。

--dump-po-strings
等價於 -D,但是輸出是 GNU gettext po (可移植對象) 文件格式
--dump-strings
等價於 -D
--help
在標準輸出顯示用法信息併成功退出
--init-file file
--rcfile file
如果 shell 是交互的,執行 file 中的命令,而不是標準的個人初始化文件 ~/.bashrc (參見下面的 啓動(INVOCATION) 章節)
--login
等價於 -l
--noediting
如果 shell 是交互的,不使用 GNU readline 庫來讀命令行
--noprofile
不讀取系統範圍的啓動文件 /etc/profile 或者任何個人初始化文件 ~/.bash_profile, ~/.bash_login, 或 ~/.profile 。默認情況下, bash 在作爲登錄 shell 啓動時讀取這些文件 (參見下面的 啓動(INVOCATION) 章節)
--norc
如果 shell 是交互的,不讀取/執行個人初始化文件 ~/.bashrc 這個選項在 shell 以 sh 命令啓動時是默認啓用的
--posix
如果默認操作與 POSIX 1003.2 標準不同的話,改變 bash 的行爲來符合標準 (posix mode)
--restricted
shell 成爲受限的 (參見下面的 受限的shell(RESTRICTED SHELL) 章節)
--rpm-requires
產生一個爲使腳本運行,需要的文件的列表。 這個選項包含了 -n 選項。 它是爲了避免進行編譯期錯誤檢測時的限制-- Backticks, [] tests, 還有 evals 不會被解釋,一些依賴關係可能丟失
--verbose
等價於 -v
--version
在標準輸出顯示此 bash 的版本信息併成功退出。

如果選項處理之後仍有參數剩餘,並且沒有指定 -c-s 選項,第一個參數將假定爲一個包含 shell 命令的文件的名字。 如果 bash 是以這種方式啓動的, $0 將設置爲這個文件的名字,位置參數將設置爲剩餘的其他參數。 Bash 從這個文件中讀取並執行命令,然後退出。 Bash 的退出狀態是腳本中執行的最後一個命令的退出狀態。 如果沒有執行命令,退出狀態是0。 嘗試的步驟是先試圖打開在當前目錄中的這個文件,接下來, 如果沒有找到,shell 將搜索腳本的 PATH 環境變量中的路徑。

login shell 登錄 shell,參數零的第一個字符是 - ,或者啓動時指定了 --login 選項的 shell。

interactive 交互的 shell,是一個啓動時沒有指定非選項的參數,並且沒有指定 -c 選項,標準輸出和標準輸入都連接到了終端 (在 isatty(3) 中判定) 的shell,或者啓動時指定了 -i 選項的 shell。如果 bash 是交互的, PS1 環境變量將被設置,並且 $- 包含 i ,允許一個 shell 腳本或者一個啓動文件來檢測這一狀態。

下列段落描述了 bash 如何執行它的啓動文件。如果這些啓動文件中的任一個存在但是不可讀取, bash 將報告一個錯誤。文件名中的波浪號 (~,tilde) 將像 EXPANSION 章節中 Tilde Expansion 段描述的那樣展開。

bash 是作爲交互的登錄 shell 啓動的,或者是一個非交互的 shell 但是指定了 --login 選項, 它首先讀取並執行 /etc/profile 中的命令,只要那個文件存在。 讀取那個文件之後,它以如下的順序查找 ~/.bash_profile, ~/.bash_login, 和 ~/.profile, 從存在並且可讀的第一個文件中讀取並執行其中的命令。 --noprofile 選項可以用來在 shell 啓動時阻止它這樣做。

當一個登錄 shell 退出時, bash 讀取並執行文件 ~/.bash_logout 中的命令,只要它存在。

當一個交互的 shell 但不是登錄 shell 啓動時, bash 從文件 ~/.bashrc 中讀取並執行命令,只要它存在。可以用 --norc 選項來阻止它這樣做。 --rcfile file 選項將強制 bash 讀取並執行文件 file 中的命令,而不是 ~/.bashrc 中的。

bash 以非交互的方式啓動時,例如在運行一個 shell 腳本時,它在環境中查找變量 BASH_ENV ,如果它存在則將它的值展開,使用展開的值作爲一個文件的名稱,讀取並執行。 Bash 運作的過程就如同執行了下列命令:

if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi

但是沒有使用 PATH 變量的值來搜索那個文件名。

如果 bash 以名稱 sh 啓動,它試圖模仿 (mimic) sh 歷史版本的啓動過程,儘可能地相似,同時也遵循 POSIX 標準。 當作爲交互式登錄 shell 啓動時,或者是非交互但使用了 --login 選項 啓動的時候,它首先嚐試讀取並執行文件 /etc/profile~/.profile, 中的命令. 選項 --noprofile 用於避免這種行爲.當使用命令 sh 來啓動一個交互式的 shell 時, bash 查找環境變量 ENV, 如果有定義的話就擴展它的值,然後使用擴展後的值作爲要讀取和執行的文件 的名稱.由於使用 sh 啓動的 shell 不會讀取和執行任何其他的啓動文件,選項 --rcfile 沒有意義.使用名稱 sh 啓動的非交互的 shell 不會讀取任何其他啓動文件.當以 sh 啓動時, bash 在讀取啓動文件之後進入 posix 模式.

bashposix 模式啓動時,(和使用 --posix 命令行參數效果相同),它遵循 POSIX 標準. 這種模式下,交互式 shell 擴展 ENV 環境變量的值,讀取並執行以擴展後值爲文件名的配置文件. 不會讀取其他文件.

Bash 試着檢測它是不是由遠程 shell 守護程序,通常爲 rshd 啓動的.如果 bash 發現它是由 rshd 啓動的,它將讀取並執行 ~/.bashrc 文件中的命令, 只要這個文件存在並且可讀.如果以 sh 命令啓動,它不會這樣做. 選項 --norc 可以用來阻止這種行爲,選項 --rcfile 用來強制讀取另一個文件,但是通常 rshd 不會允許它們, 或者用它們來啓動 shell.

如果 shell 是以與真實用戶(組) id 不同的有效用戶(組) id 來啓動的, 並且沒有 - 選項,那麼它不會讀取啓動文件, 也不會從環境中繼承 shell 函數. 環境變量中如果出現 SHELLOPTS, 它將被忽略.有效用戶 id 將設置爲真實用戶 id. 如果啓動時給出了 -
選項,那麼啓動時的行爲是類似的, 但是不會重置有效用戶 id.

下列定義在文檔餘下部分中通用.
blank 空白
一個空格或是 tab .
word 詞
一個字符序列, shell 將它們視爲一個結構單元. 也稱爲一個 token片段。
name 名稱
一個只由字母,數字和下劃線構成的詞,並且以字符或下劃線起始. 也稱爲一個 word identifier標識符.
metacharacter 元字符
一個字符, 如果不是引用的話, 將成爲詞的分隔符. 它是如下字符之一:

| & ; ( ) < > space tab

control operator 控制操作符
一個 token(標識), 擁有控制功能. 它是如下符號之一:

|| & && ; ;; ( ) | <newline>

Reserved words(保留字) 是對 shell 有特殊意義的詞. 下列詞被識別爲保留的, 如果不是引用, 並且不是一個簡單命令的起始詞 (參見下面的 shell語法("SHELL GRAMMAR") ), 也不是 case 或者 for 命令的第三個詞:

! case do done elif else esac fi for function if in select then until while { } time [[ ]]

simple command(簡單命令) 是(可選的)一系列變量賦值, 緊接着是 blank(空格) 分隔的詞和重定向, 然後以一個 control operator 結束. 第一個詞指明瞭要執行的命令, 它被作爲第 0 個參數. 其餘詞被作爲這個命令的參數.

simple command 簡單命令的返回值是它的退出狀態, 或是 128+n, 如果命令被 signal(信號) n 結束的話.

pipeline(管道) 是一個或多個命令的序列,用字符 | 分隔。管道的格式是這樣:

[time [-p]] [ ! ] command [ | command2 ... ]

命令 command 的標準輸出通過管道連接到命令 command2 的標準輸入。連接是在命令指定的任何重定向之前進行的(參見下面的 REDIRECTION 重定向)。

如果保留字 ! 作爲管道前綴,管道的退出狀態將是最後一個命令的退出狀態的邏輯非值。 否則,管道的退出狀態就是最後一個命令的。 shell 在返回退出狀態值之前,等待管道中的所有命令返回。

如果保留字 time 作爲管道前綴,管道中止後將給出執行管道耗費的用戶和系統時間。 選項 -p 將使輸出符合 POSIX 指定的格式。 環境變量 TIMEFORMAT 可以設置爲一個格式字符串,指定時間信息應當如何顯示;參見下面的 Shell Variables 環境變量TIMEFORMAT 的講述。

管道中的每個命令都作爲單獨的進程來執行(即,在一個子 shell 中啓動)。

list(序列)是一個或多個管道,用操作符 ;, &, &&, 或 ⎪⎪ 分隔的序列, 並且可以選擇用 ;, &, 或 <newline>新行符結束.

這些序列操作符中, &&⎪⎪ 優先級相同,其次是 ;&, 它們的優先級是相同的。

序列中可以有一個或多個新行符來分隔命令,而不是使用分號分隔。

如果一個命令是由控制操作符 & 結束的, shell 將在後臺的子 shell 中執行這個命令。 shell 不會等待命令執行結束,返回狀態總是 0。以分號 ; 分隔的命令會被順序執行;shell 會等待每個命令依次結束。返回狀態是最後執行的命令的返回狀態。

控制操作符 &&⎪⎪ 分別代表 AND 和 OR 序列。一個 AND 序列的形式是

command1 && command2

command2 只有在 command1 返回 0 時才被執行。

一個 OR 序列的形式是

command1 ⎪⎪ command2

command2 只有在 command1 返回非 0 狀態時才被執行。AND 和 OR 序列的返回狀態是序列中最後執行的命令的返回狀態。

compound command(複合命令) 是如下情況之一:
(list)
list 序列將在一個子 shell 中執行。變量賦值和影響 shell 環境變量的內建命令在命令結束後不會再起作用。 返回值是序列的返回值。
{ list; }
list 序列將在當前 shell 環境中執行。序列必須以一個新行符或分號結束。 這種做法也稱爲 group command(命令組)。返回值是序列的返回值。注意與元字符 ( 不同, {}reserved words(保留字),必須出現在能夠識別保留字的場合。 由於它們不會產生斷詞(cause a word break),它們和序列之間必須用空格分開。
((expression))
表達式 expression 將被求值。求值規則在下面的 算術求值 (ARITHMETIC EVALUATION) 章節中描述。如果表達式的值非零,返回值就是 0;否則返回值是 1。這種做法和 let "expression" 等價。
[[ expression ]]
返回 0 或 1,取決於條件表達式 expression 求值的情況。 表達式是由下面 CONDITIONAL EXPRESSIONS 條件表達式 章節中描述的原語(primaries) 組成。 [[]] 中的詞不會進行詞的拆分和路徑的擴展處理; 而tilde 擴展,參數和變量擴展,算術擴展,命令替換,函數替換和引用的去除則都將進行。

當使用 ==!= 操作符時,操作符右邊的字符串被認爲是一個模式,根據下面 Pattern Matching(模式匹配) 章節中的規則進行匹配。 如果匹配則返回值是 0,否則返回 1。模式的任何部分可以被引用,強制使它作爲一個字符串而被匹配。

表達式可以用下列操作符結合起來。根據優先級的降序列出如下:

( expression )
返回表達式 expression 的值。括號可以用來提升操作符的優先級。
! expression
返回真,如果表達式 expression 返回假。
expression1 && expression2
返回真,如果表達式 expression1expression2 都返回真。
expression1 || expression2
返回真,如果表達式 expression1 或者 expression2 二者之一返回真。

&&(與) 和 || 操作符不會對錶達式 expression2 求值,如果 expression1 可以決定整個條件表達式的返回值的話。

for name [ in word ] ; do list ; done
in 之後的一系列詞會被擴展,產生一個項目列表。變量 name 被依次賦以這個列表中的每個元素, 序列 list 每次都被執行。如果 in word 被忽略,那麼 for 命令遍歷 已設置的位置參數(positional parameter,參見下面的 PARAMETERS 參數), 爲每一個執行一次序列 list。 返回值是最後一個命令的返回值。如果 in 之後的詞擴展的結果是空列表,就不會執行任何命令,返回值是 0。
for (( expr1 ; expr2 ; expr3 )) ; do list ; done
首先,算術表達式 expr1 被根據下面 算術求值 (ARITHMETIC EVALUATION) 中的規則進行求值。 然後算術表達式 expr2 被循環求值,直到它等於 0。每次 expr2 結果非零時,序列 list 都被執行, 算術表達式 expr3 被求值。如果任何表達式被忽略,將被視爲執行結果是 1。 返回值是序列 list 中被執行的最後一個命令的返回值;或者是 false,如果任何表達式非法的話。
select name [ in word ] ; do list ; done
in 之後的一系列詞會被擴展,產生一個項目列表。這個擴展後的詞集合被輸出到標準錯誤上,每個前面 加上一個數字。如果 in word 被忽略,將輸出位置參數 (參見下面的 PARAMETERS 參數 章節)。 PS3 提示符將被顯示出來,等待從標準輸入得到一行輸入。如果 輸入是一個數字且顯示中有對應的詞,那麼變量 name 的值將設置爲這個詞。如果輸入一個空行,那麼詞和提示符將再次顯示出來。如果讀入了一個 EOF,命令就結束。 任何其他值將設置變量 name 爲空。讀入的行保存爲變量 REPLY. 序列 list 在每次選擇之後都會執行,直到執行了一個 break 命令。 select 的退出狀態是序列 list 中執行的最後一個命令的退出狀態,如果沒有執行命令就是 0。
case word in [ [(] pattern [ | pattern ] ... ) list ;; ] ... esac
case 命令首先擴展 word, 然後依次試着用每個 pattern 來匹配它, 使用與路徑擴展相同的匹配規則(參見下面的 Pathname Expansion 路徑擴展 章節)。如果找到一個匹配,相應的序列將被執行。找到一個匹配之後,不會再嘗試其後的匹配。 如果沒有模式可以匹配,返回值是 0。否則,返回序列中最後執行的命令的返回值。
if list; then list; [ elif list; then list; ] ... [ else list; ] fi
序列 if list 被執行。如果退出狀態是 0,then list 將被執行。否則,每個 elif 將被一次執行,如果退出狀態是 0,相應的 then list 將被執行,命令結束。 否則,else list 將被執行,如果存在的話。 退出狀態是最後執行的命令的退出狀態,或者是 0,如果所有條件都不滿足。
while list; do list; done
until list; do list; done
while 命令不斷地執行序列 do list,直到序列中最後一個命令返回 0。 until 命令和 while 命令等價,除了對條件的測試恰好相反;序列 do list 執行直到序列中最後一個命令返回非零狀態值。 whileuntil 命令的退出狀態是序列 do list 中最後一個命令的退出狀態, 或者是 0,如果沒有執行任何命令。
[ function ] name () { list; }
這樣可以定義一個名爲 name 的函數。函數體 body 是包含在 { 和 } 之間的命令序列 list。 在指定將 name 作爲一個命令運行的場合,這個序列將被執行。 函數的退出狀態是函數體最後執行的命令的退出狀態(參見下面的 FUNCTIONS 函數 章節)。

在非交互的 shell 中或者使用內建命令 shopt 啓用了 interactive_comments 選項的交互的 shell 中,以 # 起始的詞使得這個詞和所有同一行上所有剩餘的字符都被忽略。沒有啓用 interactive_comments 選項的交互式 shell 不允許出現註釋。這個選項在交互式 shell 中是默認啓用的 (參見下面的 shell 內建命令(SHELL BUILTIN COMMANDS) 章節)。

引用 Quoting 用來去掉特定字符或詞的特殊意義。引用可以用來禁止對特殊字符的處理, 阻止保留字被識別,還用來阻止參數的擴展。

上面在 DEFINITIONS 定義 中列出的每個元字符 metacharacters 對於 shell 都有特殊意義。如果要表達它的本義,必須引用它。

在使用命令行歷史擴展功能時,history expansion 字符,通常是 !,必須被引用,纔不會進行歷史擴展。

有三種引用機制:轉義字符 (escape character), 單引號和雙引號。

一個未被引用的反斜槓 (\) 是轉義字符 escape character。 它保留其後下一個字符的字面意義,除非那是一個新行符。 如果 \ 和新行符成對出現,並且反斜槓自身沒有被引用,那麼 \<newline> 被視爲續行標誌 (意思是,它被從輸入流中刪除並忽略了)。

將字符放在單引號之中,將保留引用中所有字符的字面意義。單引號不能包含在單引號引用之中,即使前面加上了反斜槓。

將字符放在雙引號中,同樣保留所有字符的字面意義,例外的情況是 $, `, 和 \。 字符 $` 在雙引號中仍然具有特殊意義。反斜槓只有後面是下列字符時纔有特殊意義: $, `, ", \, 或 <newline>. 雙引號可以包含在雙引號引用中,但要在前面加上一個反斜槓。

特殊的參數 *@ 在雙引號中有特殊意義(參見下面的 PARAMETERS 參數 章節)。

形式爲 $'string' 的詞會被特殊處理。它被擴展爲 string,其中的反斜槓轉義字符 被替換爲 ANSI C 標準中規定的字符。反斜槓轉義序列,如果存在的話,將做如下轉換:

\a
alert (bell) 響鈴
\b
backspace 回退
\e
an escape character 字符 Esc
\f
form feed 進紙
\n
new line 新行符
\r
carriage return 回車
\t
horizontal tab 水平跳格
\v
vertical tab 豎直跳格
\\
backslash 反斜槓
\'
single quote 單引號
\nnn
一個八比特字符,它的值是八進制值 nnn (一到三個數字)。
\xHH
一個八比特字符,它的值是十六進制值 HH (一到兩個十六進制數字)。
\cx
一個 ctrl-x 字符

擴展結果是單引號引用的,就好像 $ 符號不存在一樣。

雙引號引用字符串前面加上一個 $ 符號將使得這個字符串被根據當前語言環境 (locale) 來翻譯。 如果當前語言環境是 C 或者 POSIX,這個符號將被忽略。 如果這個字符串被翻譯並替換了,那麼替換結果是雙引號引用的。

一個參數 parameter 是一個儲存值的實體。它可以是一個名稱 name, 一個數字或者是下面 Special Parameters 特殊參數 章節中列出的特殊字符之一。從 shell 的角度來看,一個變量 variable 是一個由名稱 name 代表的參數。一個變量有一個值 value 以及零個或多個屬性 attibutes。屬性可以使用內建命令 declare 來設置(參見下面 shell 內建命令(SHELL BUILTIN COMMANDS) 章節中對 declare 的描述)。

如果給一個參數賦值,那麼它就被定義了。空字符串是有效的值。一旦一個變量被定義了,它只能用內建命令 unset 來取消(參見下面 shell 內建命令(SHELL BUILTIN COMMANDS) 章節).

一個變量 variable 可以用這樣的語句形式來賦值:

name=[value]

如果沒有給出值 value, 變量就被賦爲空字符串。所有值 values 都經過了波浪線擴展,參數和變量擴展,命令替換,算術擴展和引用的刪除(參見下面的 EXPANSION 擴展 章節)。如果變量設置了 integer 整數 屬性,那麼值 value 將進行算術擴展,即使沒有應用 $((...)) 擴展 (參見下面的 Arithmetic Expansion 算術擴展 章節)。 不會進行詞的拆分,除非是下面 Special Parameters 特殊參數 中提到的 "$@"。 不會進行路徑的擴展。賦值語句也出現在下列內建命令中,作爲它們的參數: declare, typeset, export, readonly, 和 local

位置參數 positional parameter 是以一或多個數字代表的參數,除了 0。位置參數是在 shell 啓動時,根據它的參數來賦值的, 也可以用內建命令 set 來重新賦值。位置參數不能用賦值語句來賦值。在一個