說說 bash 的 if 語句

說說 bash 的 if 語句

在開始先給你們列出幾個術語,不作解釋,不懂的能夠參考其它資料。
術語和符號:
退出狀態碼
$?
[...] (中括號,方括號)
[[...]] (雙中括號,雙方括號)
((...)) (雙括號)
(...) (單括號)
if語句是一種條件判斷語句。
首先,標準的if語句的語法是不含中括號的。
其語法以下:
if condition; then
    echo yes
else
    echo no
fi
即 condition 的代碼執行後,退出狀態碼爲真即執行 then 後的語句,
不然,執行else後的語句。
可是須要注意一點的是,這裏的真值是0,即返回狀態嗎爲0即爲真值,和其餘語言0表示邏輯假不一樣。
那麼如何查看單條語句的返回狀態碼?
使用下面的命令:
echo $?
返回狀態碼保存在 $? 環境變量中,每執行過一個命令後都會被更新

test 是一個 shell 內建命令
根據 test 的 man 幫助,可知 test 的功能是檢查文件類型和比較值。

先來看一條簡單的 test 語句。
test 5 -eq 5; echo $? # 輸出0
test 5 -eq 4; echo $? # 輸出1
其中的-eq是運算符。
test 支持的運算符有下面這些
# 表達式運算符
expression  # 表達式爲真(任何命令)
!   # 表達式爲假
-a  # 邏輯與 表達式1 –a 表達式2 兩個表達式都爲真
-o  # 邏輯或 表達式1 –o 表達式2 兩個表達式有一個爲真
# 字符串運算符
-n    # 字符串的長度爲非零
-z    # 字符串的長度爲零
=     # 字符串相等
!=    # 字符串不等
# 整數比較運算符
-eq   # int1 -eq int2 若是 int1 等於 int2,則爲真
-ge   # int1 -ge int2 若是 int1 大於或等於 int2,則爲真
-gt   # int1 -gt int2 若是 int1 大於 int2,則爲真
-le   # int1 -le int2 若是 int1 小於或等於 int2,則爲真
-lt   # int1 -lt int2 若是 int1 小於 int2,則爲真
-ne   # int1 -ne int2 若是 int1 不等於 int2,則爲真
# 文件運算符
-ef   # File1 –ef File2 兩個文件具備一樣的設備號和i結點號
-nt   # File1 –nt File2 文件1比文件2新
-ot   # File1 –ot File2 文件1比文件2舊
–b    # 文件存在而且是塊設備文件
–c    # 文件存在而且是字符設備文件
–d    # 文件存在而且是目錄
–e    # 文件存在
–f    # 文件存在而且是正規文件
–g    # 文件存在而且是設置了組ID
–G    # 文件存在而且屬於有效組ID
–h    # 文件存在而且是一個符號連接(同-L)
–k    # 文件存在而且設置了sticky位
–b    # 文件存在而且是塊設備文件
–L    # 文件存在而且是一個符號連接(同-h)
–o    # 文件存在而且屬於有效用戶ID
–p    # 文件存在而且是一個命名管道
–r    # 文件存在而且可讀
–s    # 文件存在而且是一個套接字
–t    # FD 文件描述符是在一個終端打開的
–u    # 文件存在而且設置了它的set-user-id位
–w    # 文件存在而且可寫
–x    # 文件存在而且可執行
*方括號
方括號是shell的內建符號,2個方括號擴起來的內容與調用test命令判斷的結果是同樣的。
須要注意的是,方括號內部緊鄰括號2邊必須有空格。
因此下面的2個test語句能夠改爲用方括號來表達。
test 5 -eq 5; echo $? # 輸出0
test 5 -eq 4; echo $? # 輸出1

[ 5 -eq 5 ]; echo $? # 輸出0
[ 5 -eq 4 ]; echo $? # 輸出1
*雙方括號
雙方括號是shell的關鍵字。
須要注意的是,雙方括號內部緊鄰括號2邊必須有空格。
雙方括號的主要功能是能夠知足其內表達式的轉義需求,就是說能夠像在其餘語言中同樣使用出現的比較符號。
好比 <,>,==,!= 等,而這些符號在單方括號中只能用作字符串的比較。
好比 &&,|| ,在單方括號中是不能使用的。

*雙括號
雙括號用來支持算術表達式。
須要注意的是隻支持整數型計算,不支持浮點數。
下面將雙括號的幾個用法舉例說明
# 1 整數擴展,輸出 true
if (( 2 * 3 == 6 )); then
    echo true
fi

# 2 三目運算符支持, 輸出 true
if (( 2 * 3 == 6 ? 1 : 0 )); then
    echo true
fi

# 3 變量賦值,輸出 6
a=5; ((a++))
echo $a

# 4 for 循環
for (( i = 0; i < 5; i++)); do
    echo $i;
done
*單括號
1 啓動一個 subshell 來執行括號內的代碼,subshell 有獨立的環境變量
# 好比下面的腳本
~$ cd /tmp/; sleep 5; cd ~
^C
/tmp$
# cd ~是沒有執行的,若是你想實現上面的邏輯,使用下面的小括號腳本便可
~$ ( cd /tmp/; sleep 5; ) cd ~
^C
~$
2 變量或者命令替換
常見 $(variable)

3 初始化數組
array=(a b c d)


接下來是一個demo,內含詳細註釋
#!/bin/bash

# 單方括號內可使用變量
SWAP_DEVICE=/dev/sda1
if [ ${SWAP_DEVICE} == "/dev/sda1" ]; then
    echo "單方括號內可使用變量"
fi

# 雙方括號內可使用變量
SWAP_DEVICE=/dev/sda1
if [[ ${SWAP_DEVICE} == "/dev/sda1" ]]; then
    echo "雙方括號內可使用變量"
fi

# 此處4被看成字符串進行比較
if [ 4 == 4 ]; then
    echo "[ 4 == 4 ] (true)"
fi

echo -e "\n***單方括號支持 test 命令的全部運算符,還支持如下的關係運算符 >,<,=,==,!="
echo -e "***這些關係運算符只限於字符串使用"
echo -e "***除此以外其餘的符號都不支持"
echo -e "\n"

# 此處的數字一樣被看成字符串處理,因此條件返回真
# 字符串的比較老是從頭開始比較第一個不相同的字符
if [[ 44 > 211 ]]; then
    echo "[[ 44 > 211 ]] (true)"
fi

# 此處的數字一樣被看成字符串處理,因此條件返回假
if [[ 4 == 2*2 ]]; then
    echo "[[ 4 == 2*2 ]] (true)"
else
    echo "[[ 4 == 2*2 ]] (false)"
    echo "等同於 [ 4 == 2*2 ] (false)"
    echo "[[ 4 == 2 * 2 ]] (error)"
fi

# && 符號不是單方括號支持的符號,可是是雙方括號支持的符號
if [[ abc = abc && def = def ]]; then
    echo "[[ abc = abc && def = def ]]"
    echo "[ abc = abc && def = def ] (error)"
fi

echo -e "\n***雙方括號只比單方括號多支持了2個符號 && 和 ||\n"

if (( 2 * 3 == 6 )); then
    echo "(( 2 * 3 == 6 )) (true)"
fi

if (( 2 * 3 == 6 ? 1 : 0 )); then
    echo "(( 2 * 3 == 6 ? 1 : 0 ))"
    echo "雙括號支持三目運算符"
fi

# 雙括號在變量賦值中的使用
a=5; ((a++))
echo "++操做  $a"

# 雙括號在 for 循環中的使用
for (( i = 0; i < 5; i++)); do
    echo "循環中${i}";
done

# 如何判斷空的變量?
# 這裏會出現一個誤區 [ ${emptyvar} = "" ],這個等於 [  = "" ],因此會報錯
# 而下面的2個方法都是可行的
emptyvar=
if [ "${emptyvar}" = "" ]; then
    echo "empty var"
fi
if [ -z ${emptyvar} ]; then
    echo "empty var"
fi

相關文章
相關標籤/搜索