『忘了再學』Shell流程控制 — 34、if條件判斷語句(二)

2022-06-20 12:00:37

1、多分支if條件語句格式

if [ 條件判斷式1 ]
    then
        當條件判斷式1成立時,執行程式1
elif [ 條件判斷式2 ]
    then
        當條件判斷式2成立時,執行程式2

…省略更多條件…

else
    當所有條件都不成立時,最後執行此程式
fi

2、練習

我們寫一個例子,用if多分支條件語句來判斷一下使用者輸入的是一個檔案,還是一個目錄。

# 需求:判斷使用者輸入的是什麼檔案
[root@localhost tmp]# vim if-elif.sh

# 編寫Shell指令碼
#!/bin/bash

# 1.接收鍵盤的輸入,並賦予變數file
read -t 30 -p "Please input a filename: " file

# 2.判斷檔案型別
# 2.1判斷file變數是否為空
if[ -z "$file" ]
    then
        # 如果為空,執行程式1,也就是輸出報錯資訊
        echo "Error,please input a filename!"

        # 退出程式,並返回值為1(把返回值賦予變數?)
        exit 10001

# 2.2判斷file的值是否存在
elif [ ! -e "$file" ]
    then
        # 如果不存在,則執行程式2
        echo "Your input is not a file!"

        # 退出程式,把並定義返回值為2
        exit 10002

# 2.3判斷file的值是否為普通檔案
elif [ -f "$file" ]
    then
        # 如果是普通檔案,則執行程式3
        echo"$file is a regulare file!"

# 2.4判斷file的值是否為目錄檔案
elif [ -d "$file" ]
    then
        # 如果是目錄檔案,則執行程式4
        echo"$file is a directory!"

# 2.5如果以上判斷都不是,則執行程式5
else
    echo "$file is an other file!"

fi

3、說明

Shell程式是順序執行的,以上面例子為例,如果當第一個條件判斷你是否輸入內容就識別內容為空了,就會輸出錯誤資訊。因為Shell程式是順序執行,所以後邊的程式還會繼續執行。那第一個條件已經判斷出錯誤了,那後邊的匹配條件肯定也符合不了,再繼續執行程式就是浪費資源了。

所以處理這類情況使用exit命令進行返回,用exit + 數位編碼(自定義)的形式進行返回(推出指令碼執行)。

什麼意思?

我們之前說過一條命令正確執行,$?變數中儲存的值是0

如果命令沒有正確執行,$?變數中儲存的值是非0

在Shell中使用exit + 數位編碼的形式進行返回,這個數位編碼就會賦值給$?變數。

最後執行完指令碼來排錯的時候,可以檢視$?變數,根據$?變數的值,我們就可以很方便的找到Shell指令碼中具體的內容,來排查程式出現的問題。

總結:

不符合規範的輸入,也就是可能使程式報錯的輸入,可以用exit + 數位編碼的形式進行返回,如上面練習中的2.1和2.2。

而符合規範的輸入,直接匹配選項進行處理即可,不用寫返回,如2.3和2.4。

4、綜合練習

計算器指令碼改進:

#!/bin/bash
# 字元介面加減乘除計算器。

# 1.通過read命令接收要計算的數值,並賦予變數num1和num2
read -t 30 -p "Please input num1: " num1
read -t 30 -p "Please input num2: " num2

# 2.通過read命令接收要計算的符號,並賦予變數ope.
read -t 30 -p "Please input a operator: " ope

# 第一層判斷
# 用來判斷num1、num2和ope中都有值。
# -n選項:判斷後邊的字串是否為空,非空為真。
# -a選項:邏輯與。
if [ -n "$num1" -a -n "$num2" -a -n "$ope" ]
    then
        # 判斷輸入的num1和num2內容是否是純數位 
        # 判斷一個變數的內容是否是純數位有很多方法,下面一種是簡單好理解的。
        # 定義變數test1和test2的值為$(命令)的結果。
        test1=$(echo $num1 | sed 's/[0-9]//g')
        test2=$(echo $num2 | sed 's/[0-9]//g')

        # 說明:
        # 就是通過sed命令,把變數test1值中的每一個字元,只要是0-9的內容,就替換為空。
        # 最後如果test1的值最後為空,證明test1變數中的內容全部為數位,因為全部被替換了。
        # 如果test1的值最後不為空,證明test1變數中的內容有非數位,即test1非純數位。

        # 第二層判斷,用來判斷num1和num2為數值。
        # 如果變數test1和test2的值為空,則證明numl和num2是數位.
        # -z選項:判斷字串是否為空(為空返回真)
        # -a選項:邏輯與。
        if [ -z "$test1" -a -z "$test2" ]
            then
                # 如果test1和test2是數位,則執行以下命令。

                # 第三層判斷用來確認運運算元。
                # 確認變數$ope中是什麼運運算元。
                # 如果是加號則執行加法運算。
                if [ "$ope" == '+' ]
                    then
                        value=$(($num1+$num2))
                # 如果是減號,則執行減法運算。
                elif [ "$ope" == '-' ]
                    then
                        value=$(($num1-$num2))
                # 如果是乘號,則執行乘法運算。
                elif [ "$ope" == '*' ]
                    then
                        value=$(($num1*$num2))
                # 如果是除號,則執行除法運算。
                elif [ "$ope" == '/' ]
                    then
                        value=$(($num1/$num2))

                else
                    # 如果運運算元不匹配,提示輸入有效的符號
                    echo "Please enter a valid symbol."
                    # 並退出程式,返回錯誤程式碼10。
                    exit 10

                fi

        else
            # 如果test1和test2不為空,說明numl和num2不是數位。
            # 則提示輸入有效的數值。
            echo "Please enter a valid value."
            # 並退出程式,返回錯誤程式碼11。
            exit 11
        fi
else
    echo "qing input neirong."
    exit 12
fi

# 輸出數值運算的結果。
echo "$num1 $ope $num2:$value"

注意:

建議if條件語句巢狀最多不能超過三層。

如果寫在一起if條件語句巢狀過多,則可以拆開寫。