一、簡介
Shell程式設計中循環指令用于特定條件下決定某些語句重複執行的控制方式,有三種常用的循環語句:for、while和until。while循環和for循環屬于“當型循環”,而until屬于“直到型循環”。循環控制符:break和continue控制流程轉向。
二、詳解
1、for循環
(1)for循環有三種結構:一種是清單for循環,第二種是不帶清單for循環。第三種是類C風格的for循環。
(2)清單for循環
1. #!/bin/bash
2.
3. for varible1 in {1..5}
4. #for varible1 in 1 2 3 4 5
5. do
6. "Hello, Welcome $varible1 times "
7. done
- do和done之間的指令稱為循環體,執行次數和list清單中常數或字元串的個數相同。for循環,首先将in後list清單的第一個常數或字元串指派給循環變量,然後執行循環體,以此執行list,最後執行done指令後的指令序列。
- Sheel支援清單for循環使用略寫的計數方式,1~5的範圍用{1..5}表示(大括号不能去掉,否則會當作一個字元串處理)。
- Sheel中還支援按規定的步數進行跳躍的方式實作清單for循環,例如計算1~100内所有的奇數之和。
1. #!/bin/bash
2. sum=0
3.
4. for i in {1..100..2}
5. do
6. "sum+=i"
7. done
8.
9. echo "sum=$sum"
通過i的按步數2不斷遞增,計算sum值為2500。同樣可以使用seq指令實作按2遞增來計算1~100内的所有奇數之和,for i in $(seq 1 2 100),seq表示起始數為1,跳躍的步數為2,結束條件值為100。
- for循環對字元串進行操作,例如通過for循環顯示目前目錄下所有的檔案。
1. #!/bin/bash
2.
3. for file in $( ls )
4. #for file in *
5. do
6. "file: $file"
7. done

也可一使用for file in *,通配符*産生檔案名擴充,比對目前目錄下的所有檔案。
- for通過指令行來傳遞腳本中for循環清單參數
1. #!/bin/bash
2.
3. echo "number of arguments is $#"
4.
5. echo "What you input is: "
6.
7. for argument in "$@"
8. do
9. "$argument"
10. done
$#表示參數的個數,$@表示參數清單而$*則把所有的參數當作一個字元串顯示。
(3)不帶清單for循環
由使用者制定參數和參數的個數,與上述的for循環清單參數功能相同。
1. #!/bin/bash
2.
3. echo "number of arguments is $#"
4.
5. echo "What you input is: "
6.
7. for argument
8. do
9. "$argument"
10. done
比上述代碼少了
$@參數清單,$*參數字元串
。
(4)類C風格的for循環
也被稱為計次循環
1. #!/bin/bash
2.
3. for((integer = 1; integer <= 5; integer++))
4. do
5. "$integer"
6. done
for中第一個表達式(integer = 1)是循環變量賦初值的語句,第二個表達式(integer <= 5)決定是否進行循環的表達式,退出狀态為非0時将退出for循環執行done後的指令(與C中的for循環條件是剛好相反的)。第三個表達式(integer++)用于改變循環變量的語句。
Sheel中不運作使用非整數類型的數作為循環變量,循環條件被忽略則預設的退出狀态是0,for((;;))為死循環。
類C的for循環計算1~100内所有的奇數之和。
1. #!/bin/bash
2.
3. sum=0
4.
5. for(( i = 1; i <= 100; i = i + 2 ))
6. do
7. "sum += i"
8. done
9.
10. echo "sum=$sum"
2、while循環
也稱為前測試循環語句,重複次數是利用一個條件來控制是否繼續重複執行這個語句。為了避免死循環,必須保證循環體中包含循環出口條件即表達式存在退出狀态為非0的情況。
(1)計數器控制的while循環
1. #!/bin/bash
2.
3. sum=0
4.
5. i=1
6.
7. while(( i <= 100 ))
8. do
9. "sum+=i"
10. "i += 2"
11. done
12.
13. echo "sum=$sum"
指定了循環的次數500,初始化計數器值為1,不斷測試循環條件i是否小于等于100。在循環條件中設定了計數器加2來計算1~100内所有的奇數之和。
(2)結束标記控制的while循環
設定一個特殊的資料值(結束标記)來結束while循環。
1. #!/bin/bash
2.
3. echo "Please input the num(1-10) "
4. read num
5.
6. while [[ "$num" != 4 ]]
7. do
8. if [ "$num" -lt 4 ]
9. then
10. "Too small. Try again!"
11. read num
12. "$num" -gt 4 ]
13. then
14. "To high. Try again"
15. read num
16. else
17. exit 0
18. fi
19. done
20.
21. echo "Congratulation, you are right! "
例:通過結束标記控制實作階乘的操作
1. #!/bin/bash
2.
3. echo "Please input the num "
4. read num
5.
6. factorial=1
7.
8. while [ "$num" -gt 0 ]
9. do
10. "factorial= factorial*num"
11. "num--"
12. done
13.
14. echo "The factorial is $factorial"
(3)标志控制的while循環
使用使用者輸入的标志值來控制循環的結束(避免不知道循環結束标志的條件)。
1. #!/bin/bash
2.
3. echo "Please input the num "
4. read num
5.
6. sum=0
7. i=1
8.
9. signal=0
10.
11. while [[ "$signal" -ne 1 ]]
12. do
13. if [ "$i" -eq "$num" ]
14. then
15. "signal=1"
16. "sum+=i"
17. "1+2+...+$num=$sum"
18. else
19. "sum=sum+i"
20. "i++"
21. fi
22. done
标志控制的while循環求1~n的累加和,循環變量值小于100執行else累加同時循環變量加1,直到循環變量值等于100将标志值設定為1,并輸出。
标志控制的while循環與結束标記控制的while循環的差別是使用者無法确定無法确定結束标志,隻能程式運作後确定結束标志。兩者也可以互相轉化。
(4)指令行控制的while循環
使用指令行來指定輸出參數和參數個數,通常與shift結合使用,shift指令使位置變量下移一位($2代替$1、$3代替$2,并使$#變量遞減),當最後一個參數顯示給使用者,$#會等于0,$*也等于空。
1. #!/bin/bash
2.
3. echo "number of arguments is $#"
4.
5. echo "What you input is: "
6.
7. while [[ "$*" != "" ]]
8. do
9. "$1"
10. shift
11. done
循環條件可以改寫為while[[ "$#" -ne 0 ]],等于0時退出while循環
3、until循環
until指令和while指令類似,while能實作的腳本until同樣也可以實作,但差別是until循環的退出狀态是不為0,退出狀态是為0(與while剛好相反),即whie循環在條件為真時繼續執行循環而until則在條件為假時執行循環。
1. #!/bin/bash
2.
3. i=0
4.
5. until [[ "$i" -gt 5 ]] #大于5
6. do
7. "square=i*i"
8. "$i * $i = $square"
9. "i++"
10. done
4、循環嵌套
一個循環體内又包含另一個完整的循環結構,在外部循環的每次執行過程中都會觸發内部循環,for、while、until可以互相嵌套。
(1)嵌套循環實作九九乘法表
1. #!/bin/bash
2.
3. for (( i = 1; i <=9; i++ ))
4. do
5.
6. for (( j=1; j <= i; j++ ))
7. do
8. "temp = i * j"
9. "$i*$j=$temp "
10. done
11.
12. "" #output newline
13. done
(2)for循環嵌套實作*圖案排列
1. #!/bin/bash
2.
3. for ((i=1; i <= 9; i++))
4. do
5. j=9;
6. while ((j > i))
7. do
8. " "
9. "j--"
10. done
11. k=1
12. while ((k <= i))
13. do
14. "*"
15. "k++"
16. done
17. ""
18. done
外層for循環嵌套了兩個内層while循環,先列印空格在列印*号形成圖案。
5、循環控制符break和continue
若須退出循環可使用break循環控制符,若退出本次循環執行後繼續循環可使用continue循環控制符。
(1)break
在for、while和until循環中break可強行退出循環,break語句僅能退出目前的循環,如果是兩層循環嵌套,則需要在外層循環中使用break。
1. #!/bin/bash
2.
3. sum=0
4. for (( i=1; i <= 100; i++))
5. do
6. "sum+=i"
7.
8. if [ "$sum" -gt 1000 ]
9. then
10. "1+2+...+$i=$sum"
11. break
12. fi
13. done
(2)continue
在for、while和until中用于讓腳本跳過其後面的語句,執行下一次循環。continue用于顯示100内能被7整除的數。
1. #!/bin/bash
2.
3. m=1
4. for (( i=1; i < 100; i++ ))
5. do
6. "temp1=i%7" #被7整除
7.
8. if [ "$temp1" -ne 0 ]
9. then
10. continue
11. fi
12.
13. "$i "
14.
15. "temp2=m%7" #7個數字換一行
16.
17. if [ "$temp2" -eq 0 ]
18. then
19. ""
20. fi
21.
22. "m++"
23. done
6、select結構
select結構從技術角度看不能算是循環結構,隻是相似而已,它是bash的擴充結構用于互動式菜單顯示,功能類似于case結構比case的互動性要好。
(1)select帶參數清單
1. #!/bin/bash
2.
3. echo "What is your favourite color? "
4.
5. select color in "red" "blue" "green" "white" "black"
6. do
7. break
8. done
9.
10. echo "You have selected $color"
(2)select不帶參數清單
該結構通過指令行來傳遞參數清單,由使用者自己設定參數清單。
1. #!/bin/bash
2.
3. echo "What is your favourite color? "
4.
5. select color
6. do
7. break
8. done
9.
10. echo "You have selected $color"
三、總結
(1)循環結構中互相嵌套組成更複雜的流程,并結合break和continue可以實作很多複雜的運算。
(2)可以結合其他語言的文法有助于更好的了解循環結構。