shell 括號
test 和 []符號
兩者是一樣的,在命令行里test expr和[ expr ]的效果相同。要注意的有:
- test中可用的比較運算符只有==和!=
- 兩者都是用於字符串比較的,不可用於整數比較,整數比較只能使用-eq, -gt這種形式。
- 無論是字符串比較還是整數比較都千萬不要使用大於號小於號。當然,如果你實在想用也是可以的,對於字符串比較可以使用尖括號的轉義形式,如果比較"ab"和"bc":[ ab \< bc ],結果為真,也就是返回狀態為0.
test 的基本作用
test的三個基本作用是判斷文件、判斷字符串、判斷整數。支持使用與或非將表達式連接起來。
[[]] 符號
這是內置在shell中的一個命令,支持字符串的模式匹配(使用=~操作符時甚至支持shell的正則表達式)。邏輯組合可以不使用test的-a,-o而使用&&,||這樣更親切的形式(針對c、Java程序員)。當然,也不用想的太復雜,基本只要記住:
- 字符串比較時可以把右邊的作為一個模式(這是右邊的字符串不加雙引號的情況下。如果右邊的字符串加了雙引號,則認為是一個文本字符串。),而不僅僅是一個字符串,比如[[ hello == hell? ]],結果為真。
- 使用[]和[[]]的時候不要吝嗇空格,每一項兩邊都要有空格,[[ 1 == 2 ]]的結果為“假”,但[[ 1==2 ]]的結果為“真”!后一種顯然是錯的。
let和(())符號
兩者也是一樣的(或者說基本上是一樣的,雙括號比let稍弱一些)。主要進行算術運算(上面的兩個都不行),也比較適合進 行整數比較,可以直接使用熟悉的<,>等比較運算符。可以直接使用變量名如var而不需要$var這樣的形式。支持分號隔開的多個表達式
"[]" , "[[]]" 和 "(())"對比
- 首先,盡管很相似,但是從概念上講,二者是不同層次的東西。
- "[[",是關鍵字,許多shell(如ash bsh)並不支持這種方式。ksh, bash(據說從2.02起引入對[[的支持)等支持。
- "["是一條命令, 與test等價,大多數shell都支持。在現代的大多數sh實現中,"["與"test"是內部(builtin)命令,換句話說執行"test"/"["時不會調用/some/path/to/test這樣的外部命令(如果有這樣的命令的話)。
- [[]]結構比Bash版本的[]更通用。在[[和]]之間的所有的字符都不會被文件擴展或是標記分割,但是會有參數引用和命令替換。用[[ ... ]]測試結構比用[ ... ]更能防止腳本里的許多邏輯錯誤。比如說,&&,||,<和>操作符能在一個[[]]測試里通過,但在[]結構會發生錯誤。
- (( ))結構擴展並計算一個算術表達式的值。如果表達式值為0,會返回1或假作為退出狀態碼。一個非零值的表達式返回一個0或真作為退出狀態碼。這個結構和先前test命令及[]結構的討論剛好相反。
- [ ... ]為shell命令,所以在其中的表達式應是它的命令行參數,所以串比較操作符">" 與"<"必須轉義,否則就變成IO改向操作符了(請參看上面2中的例子)。在[[中"<"與">"不需轉義;由於"[["是關鍵字,不會做命令行擴展,因而相對的語法就稍嚴格些。例如在[ ... ]中可以用引號括起操作符,因為在做命令行擴展時會去掉這些引號,而在[[ ... ]]則不允許這樣做。