在shell指令碼中也有各種各樣的流程控制語句,例如if…else,case , while,for回圈語句等等。儘管這些流程控制語句的含義和其他語言都是一樣的,但是其使用細節和C/C++語言裏面的使用有些許不同。接下來就一一來看一下這些流程控制語句的使用,也會結合上篇文章中的各種運算子。
if…else是條件判斷語句,根據if…else的數目大致可以分爲單if語句,if…else語句以及if…elseif…else語句。
單if語句的一般形式:
if 條件
then
程式碼塊
fi
如果滿足條件則執行程式碼塊。fi是if反過來寫,表示該if語句到此結束。
if…else語句的一般形式:
if 條件
then
程式碼塊1
else
程式碼塊2
fi
如果滿足條件則執行程式碼塊1,不滿足則執行程式碼塊2。
多if…else的一般形式:
if 條件1
then
程式碼塊1
elif 條件2
then
程式碼塊2
else
程式碼塊3
fi
如果滿足條件1則執行程式碼1,滿足條件2則執行程式碼塊2,否則就執行程式碼塊3.
看一個範例:判斷兩數是否相等。
#!/bin/bash
a=1
b=1
if [ $a==$b ]
then
echo "兩數相等"
else
echo "兩數不相等"
fi
除了使用==號來判斷兩數相等,也可以用-eq來判斷是否相等。上一篇文章的運算子中有講,如下:
#!/bin/bash
a=1
b=1
if [ $a -eq $b ]
then
echo "兩數相等"
else
echo "兩數不等"
fi
有兩點需要強調:
1.if語句結束後記得要帶上fi,以表示if語句到此結束。
2.在判斷條件中,中括號兩邊和變數之間都要有空格。
看完兩數相等,再看一個比較數位大小的shell,充分利用if…else以及一些其他比較運算子。
#!/bin/bash
a=1
b=2
if [ $a -eq $b ]
then
echo "兩數相等"
elif [ $a -gt $b ]
then
echo "a大於b"
else
echo "b大於a"
fi
case爲多選擇語句,當分支多,判斷條件簡單時可以採用case語句。case語句的一般形式如下:
case 值 in
值1)
程式碼塊1
;;
值2)
程式碼塊2
;;
值3)
程式碼塊3
;;
*)
程式碼塊4
;;
esac
當case中的值與值1,值2或值3其中的值相等時,就會執行相對應的程式碼塊。*則表示如果case中的值與1,2,3都不匹配,則執行程式碼塊4.類似於c語言switch語句中的default。另外,每一個程式碼塊後跟着兩個分號,類似於c語言中的break,表示一旦執行完匹配的程式碼塊後不再匹配其他的值。舉例,如果case中的值與值1匹配,執行程式碼塊1之後就跳出該case語句。
esac是case反過來的寫,表示一個case語句的結束。接下來看幾個範例:
#!/bin/bash
echo "請輸入1,2,3其中一個數字"
read num
case $num in
1)
echo "你輸入了1"
;;
2)
echo "你輸入了2"
;;
3)
echo "你輸入了3"
;;
*)
echo "你輸入的數位不是1,2,3中的一個"
;;
esac
在本例中case中的待匹配的值,我們使用了一個變數num,但其實該值不僅僅可以是一個變數,還可以是一個表達式甚至是命令的結果等等。上面列舉的例子是shell中的case最常見的用法。
在shell中,for回圈有兩種一般的書寫形式,分別是c語言風格和Python風格的for回圈。先來看c語言風格的for語句:
for((exp1;exp2;exp3))
do
程式碼塊
done
for回圈的執行過程爲:執行exp1,判斷exp2是否爲真,如果爲假,直接跳出for回圈;如果爲真,就執行程式碼塊,再執行exp3;此後的回圈順序就是判斷exp2->程式碼塊2->exp3,只要exp2爲真就一直回圈知道exp2爲假結束回圈。
說了這麼多,其實挺囉嗦的,學過程式設計的這個語句應該也是一看就懂了。下面 下麪用一張流程圖說明該過程:
再通過一個簡單的例子看一下shell中for回圈的使用
#!/bin/bash
sum=0
for ((i=1;i<=10;i++))
do
((sum+=i))
done
echo "1+..+10=${sum}"
在for回圈中的三個表達式任何一個都是可以省略的,甚至極端時三個也可以省略:
for ((;;))
Python風格的for回圈:
for val in value_list
do
程式碼塊
done
其中val表示變數,value_list表示取值列表,每一次回圈都會從value_list中按順序取出一個值賦給val,val被賦值後再進入到回圈體的程式碼塊中執行,直到取值列表的值都被取完了,回圈也就結束了。
對於取值列表,我們既可以給出其具體的值,也可以給出一個範圍,也可以由某個命令的輸出作爲取值列表。
看下面 下麪這個範例,就是把取值列表的每一個具體的值都給出來。
#!/bin/bash
sum=0
for val in 1 2 3 4 5
do
((sum+=val))
done
echo "1+..5=${sum}"
但是如果要計算1到100,或者1到500的和,顯然不可能像上例中一樣給具體的值。但是我們可以通過指定一個取值範圍,簡化取值列表。
取值範圍的語法如下:
{start..end}
注意:起始值和終止值之間是由兩個點號連線。
瞭解了語法之後,我們來計算一下1到100的和。
#!/bin/bash
sum=0
for val in {1..100}
do
((sum+=val))
done
echo "1+..100=$sum"
再來看看由命令的輸出作爲取值列表的例子:
#!/bin/bash
sum=0
for val in $(seq 100)
do
((sum+=val))
done
echo "1+..+100=$sum"
seq命令是產生序列的命令。seq命令的用法在我另一篇部落格seq詳解有詳細介紹。
while語句也是shell中比較常用的回圈語句,其工作流程就是當滿足條件時,執行回圈體,一旦條件不滿足就跳出回圈。其一般形式爲:
while 條件
do
程式碼塊
done
使用while回圈計算10以內的和。
#!/bin/bash
sum=0
i=0
while ((i<=10))
do
((sum+=i))
((i++))
done
echo "1+..+10=$sum"
until語句也是一個回圈控制的語句,和while差不多的用法。只不過while是判斷條件爲真時進入回圈體,until則是判斷條件爲假的進入回圈體。其一般形式和while也是一樣的。
until 條件
do
程式碼塊
done
下面 下麪來看一下until語句如何計算1到10的和。
#!/bin/bash
sum=0
i=0
until ((i>10))
do
((sum+=i))
((i++))
done
echo "1+..+10=$sum"