shell 中()、[]、{}、(())、[[]]等各種括號的使用


11 shell中內置關鍵字[[]]:檢查條件是否成立

1、小括號、圓括號()

1.1 單小括號()

用途
 
 
命令組
  • 括號中的命令將會新開一個子shell順序執行,所以括號中的變量不能夠被腳本余下的部分使用。
  • 括號中多個命令之間用分號隔開,最后一個命令可以沒有分號,
  • 各命令和括號之間不必有空格。
22 shell組命令與子進程
命令替換
  • 等同於 cmd ,shell掃描一遍命令行,發現了(cmd)結構,便將(cmd)中的cmd執行一次,得到其標准輸出,再將此輸出放到原來命令。
  • 有些shell不支持,如tcsh。
3shell命令替換
初始化數組 如array=(a b c d) 5shell中的數組

1.2 雙小括號(())

  1. 整數擴展。這種擴展計算是整數型的計算,不支持浮點型。((exp))結構擴展並計算一個算術表達式的值,如果表達式的結果為0,那么返回的退出狀態碼為1,或者是"假",而一個非零值的表達式所返回的退出狀態碼將為0,或者是"true"。若是邏輯判斷,表達式exp為真則為1,假則為0。
  2. 只要括號中的運算符、表達式符合C語言運算規則,都可用在$((exp))中,甚至是三目運算符。作不同進位(如二進制、八進制、十六進制)運算時,輸出結果全都自動轉化成了十進制。如:echo $((16#5f)) 結果為95,(16進位轉十進制)
  3. 單純用 (( )) 也可重定義變量值,比如 a=5; ((a++)) 可將 $a 重定義為6.
  4. 常用於算術運算比較,雙括號中的變量可以不使用符號前綴。括號內支持多個表達式用逗號分開。只要括號中的表達式符合C語言運算規則,比如可以直接使用for((i=0;i<5;i++)),如果不使用雙括號,則為for i in seq 0 4或者for i in 0..4。再如可以直接使用if ((i<5)), 如果不使用雙括號,則為if [ $i -lt 5 ]。

1.3 簡單測試

命令
結果
知識點

for ((i=0;i<5;i++));do echo -n $i;done

01234

echo 加上-n參數可以使數據字符串后不再換行

for i in $(seq 0 4);do echo -n $i;done

01234  

for i in `seq 0 4`;do echo -n $i;done

   

for i in {0..4};do echo -n $i;done

   

2、中括號、方括號[]

2.1 單中括號[]

  • bash 的內部命令,[]和test是等同的。這個命令把它的參數作為比較表達式或者作為文件測試,並且根據比較的結果來返回一個退出狀態碼。
  • test和[] 10 shell test命令
  • 字符范圍。用作正則表達式的一部分,描述一個匹配的字符范圍。作為test用途的中括號內不能使用正則。
  • 在一個array 結構的上下文中,中括號用來引用數組中每個元素的編號。

2.2 雙中括號[[]]

  1. [[]]是 bash 程序語言的關鍵字。並不是一個命令,[[ ]] 結構比[ ]結構更加通用。在[[和]]之間所有的字符都不會發生文件名擴展或者單詞分割,但是會發生參數擴展和命令替換。
  2. 支持字符串的模式匹配,使用=~操作符時甚至支持shell的正則表達式。字符串比較時可以把右邊的作為一個模式,而不僅僅是一個字符串,比如[[ hello == hell? ]],結果為真。[[ ]] 中匹配字符串或通配符,不需要引號。
  3. 使用[[ … ]]條件判斷結構,而不是[ … ],能夠防止腳本中的許多邏輯錯誤。比如,&&、||、<和> 操作符能夠正常存在於[[ ]]條件判斷結構中,但是如果出現在[ ]結構中的話,會報錯。比如可以直接使用if [[ $a !=1 && $a != 2 ]], 如果不適用雙括號, 則為if [ $a -ne 1] && [ $a != 2 ]或者if [ $a -ne 1 -a $a != 2 ]
  4. bash把雙中括號中的表達式看作一個單獨的元素,並返回一個退出狀態碼。

2.3 簡單測試

[[ 2 ­lt 3 ]] && echo true true
[[ 2 \< 3 ]] && echo true bash: 期待二元條件運算符
bash: `\<' 附近有語法錯誤
[ 2 \< 3 ] && echo true true
[ 2 < 3 ] && echo true bash: 3: 沒有那個文件或目錄

3、大括號、花括號{}

3.1常規用法

      1.花括號拓展。(通配(globbing))將對花括號中的文件名做擴展。在大括號中,不允許有空白,除非這個空白被引用或轉義。

    • 對大括號中的以逗號分割的文件列表進行拓展。如touch {a,b}.txt 結果為a.txt b.txt。
    • 對大括號中以點點()分割的順序文件列表起拓展作用,如:touch {a..d}.txt 結果為a.txt b.txt c.txt d.txt。

      2.代碼塊,又被稱為內部組,這個結構事實上創建了一個匿名函數 。與小括號中的命令不同,花括號內的命令不會新開一個子shell運行,即腳本余下部分仍可使用括號內變量。括號內的命令間用分號隔開,最后一個也必須有分號。{}的第一個命令和左括號之間必須要有一個空格。

3.2 幾種特殊的替換結構

命令 替換規則 舉栗 注意點
$ {var:-string}

若變量var為空,則用在命令行中用string來替換{var:−string},var的值不變

變量var不為空時,則用變量var的值來替換{var:-string},var的值不變

  1. a=2
  2. echo $a #result is 2
  3. echo ${a:-123} #result is 2
  4. echo ${b:-123} #result is 123
  5. echo $a #result is 2
  6. echo $b #result is empty
${var:−string}的值會變化,但是${var}的值沒有變化
$ {var:=string}

當var為空時,string會賦給var與{var:−string},var的值變化

當var不為空時,會用變量var的值來替換{var:−string}

與上述原則不同的是當var為空時,var會被賦值,很常用的一種用法是,判斷某個變量是否賦值,沒有的話則給它賦上一個默認值

  1. a=2
  2. echo ${a:=123} #result is 2
  3. echo ${a} #result is 2
  4. echo ${b:=123} #result is 123
  5. echo $b #result is 123

若變量var為空,則{var:=string}與{var}的值都會被賦值為string

若變量var不為空,則{var:=string}與{var}的值都還為var

$ {var:+string}

替換規則與第一種完全相反

當var不為空時用string來替換{var:−string},若var為空時則不替換

不管var是否為空,${var}的值都不會發生變化

a=2

echo ${a:+44} #result is 44

echo ${a} #result is 2

echo ${c} #result is empty

echo ${c:+44} #result is empty

echo ${c} #result is empty

 
$ {var:?string}

若變量var不為空,則用變量var的值來替換${var:?string};

若變量var為空,則把string輸出到標准錯誤中,並從腳本中退出。

我們可利用此特性來檢查是否設置了變量的值。

#!/bin/bash

var=4

echo '${var:?33}: '${var:?33}

echo '${s:?33}: '${s:?33}

echo 'aaaaaaaaaaaa'

執行:bash test1.sh 2>result.h

結果:${var:?33}: 4

執行: cat result.h

結果:test1.sh: line 4: s: 33

當var為空時,會從腳本中退出,所以沒有打印aaaaaaaaaaaa

tips:在上面替換結構中string不一定是常值的,可用另外一個變量的值或是一種命令的輸出。


3.3 四種模式匹配替換結構

字符串的截取:2shell中處理字符串

3.4 字符串的提取和替換

2shell中處理字符串

4、$符號后面的括號()

  • ${a} 變量a的值, 在不引起歧義的情況下可以省略大括號。
  • (cmd)命令替換,和cmd效果相同,結果為shell命令cmd的輸出,不過某些Shell版本不支持()形式的命令替換, 如tcsh。
  • $((expression)) 和 expr expression 效果相同, 計算數學表達式expr的數值。 其中expr只要符合C語言的運算規則即可, 甚至三目運算符和邏輯表達式都可以計算。

5、使用注意

單小括號,(cmd1;cmd2;cmd3) 新開一個子shell順序執行命令cmd1,cmd2,cmd3, 各命令之間用分號隔開最后一個命令后可以沒有分號
單花括號,{ cmd1;cmd2;cmd3;} 在當前shell順序執行命令,cmd1,cmd2,cmd3, 各命令之間用分號隔開最后一個命令后必須有分號,第一條命令和左括號之間必須用空格隔開
對{}和()而言, 括號中的重定向符只影響該條命令,而括號外的重定向符影響到括號中的所有命令

0.[[]] [] (())的對比

[[ ]] 對數字的比較不友好,所以使用 if 判斷條件時,建議用(())來處理整型數字,用[[]]來處理字符串或者文件。

 
用法
說明
腳本
支持邏輯運算符
(())

((expression))

不需要注意空格

  1. 在 (( )) 中使用變量可以加也可以不加$前綴,(( )) 會自動解析變量名
  2. 只用於進行整數運算
  3. 可以使用<、<=、>、>=等進行整數運算
  4. 表達式可以只有一個,也可以有多個,多個表達式之間以逗號,分隔
  5. 對於多個表達式的情況,以最后一個表達式的值作為整個 (( )) 命令的執行結果
  6. 支持邏輯運算符,邏輯運算符為&& ||
  ((a>7 && b==c))
test/[]

test expression

或[ expression ]

注意空格

  1.  Shell 內置命令
  2. >、<、== 只能用來比較字符串
  3. 比較數字需要使用 -eq、-gt 等選項;
  4. 不管是比較字符串還是數字,test 都不支持 >= 和 <=。
  5. 變量名建議用雙引號""包圍起來
  6. 比較字符串時需要對 >、< 進行轉義
  7. 支持邏輯運算符,邏輯運算符為-o -a
  1. [ -z "$str1" ]||[ -z "$str2" ]#建議對變量名加雙引號
  2. [[ $str1 \$str2 ]] #需要對 < 進行轉義

使用邏輯運算符

[ -z "$str1" ] || [ -z "$str2" ]

使用-o -a !選項

[ -z "$str1" -o -z "$str2" ]

[ -z "$str1" || -z "$str2" ] ×

[[]]

[[ ]] 是 test 的升級版,對細節進行了優化,並且擴展了一些功能

[[ expression ]]

注意空格

  1. Shell 內置關鍵字,不是命令,在使用時沒有給函數傳遞參數的過程,所以 test 命令的某些注意事項在 [[ ]] 中就不存在了
  2.  >、<、== 只能用來比較字符串
  3. 比較數字需要使用 -eq、-gt 等選項;
  4. 不需要把變量名用雙引號""包圍起來,即使變量是空值,也不會出錯。
  5. 不需要、也不能對 >、< 進行轉義,轉義后會出錯
  6. 支持正則表達式!!

    在 Shell [[ ]] 中,可以使用=~來檢測字符串是否符合某個正則表達式,它的用法為:[[ str =~ regex ]]    其中,str 表示字符串,regex 表示正則表達式。

  7. 支持邏輯運算符,邏輯運算符為&& ||
  1.  [[ -z $str1 ]] || [[ -z $str2 ]] #不需要對變量名加雙引號
  2. [[ $str1 $str2 ]] #不需要也不能對 < 進行轉義

[[ ]] 剔除了 test 命令的-o-a選項,你只能使用 || 和 &&

使用邏輯運算符

[[ -z $str1 ]]||[[ -z $str2 ]]

[[ -z $str1 -o -z $str2 ]] ×

使用邏輯運算符

[[ -z $str1 || -z $str2 ]]

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM