什麽是循環語句、死循環?
循環語句:將一段代碼重復執行0、1或多次;它有進入條件與退出條件。
重復運行多少次?我們如何設定循環語句的重復次數?
為了設定循環語句的重復次數於是就有了進入條件與退出條件。
進入條件:條件滿足時進入循環。
退出條件:不符合條件退出循環。
一種特殊的循環:死循環
死循環:在編程中,一個無法靠自身的控制終止的循環稱為"死循環"。死循環的出現有兩種情況:
1、因程序需要刻意寫的;2、因程序員的失誤造成的。
第二種的死循環通常會造成比較嚴重的程序錯誤,甚至會因此而影響物理機。因此死循環的使用需要合理的設計。
實驗環境CentOS7.2
本文重要的三個循環語句:for、while、until
………………………………………………………………………………………………………………………
for循環
for語句的使用格式:
for NAME in LIST(列表); do
循環體
done
列表生成方式:
(1) 整數列表
{start..end}
$(seq start [[step]end])
(2) glob
/etc/rc.d/rc3.d/K*
(3) 命令
………………………………………………………………………………………………………………………
下面以一個例子看看for的具體作用
示例:計算1+2+...+10的值
#!/bin/bash #sum the value of "1+2+...+10" #author chawan #date:20160906 declare -i sum=0 for x in {1..10};do let sum+=$x done echo "The sum is : $sum"
運行腳本0906-1結果如下
[root@docker hmworks]# sh 0906-1 The sum is : 55
上面使用了第一種的整數列表中的第一種形式,這裏如果是“1+2+...+n”這種形式那麽{start..end}就不再適用,此時就只能使用$(seq start [[step]end])。下面再舉一個例子說明
示例:計算“1+2+...+n”的值
#!/bin/bash #sum “1+2+...+n” #author chawan #date:20160906 declare -i sum=0 #以交互的方式輸入一個正整數 read -p "Please inset a number :" num #判斷輸入的數是否為空,為空則提示並退出 [ -z $num ] && echo "Please input a number!" && exit 1 #判斷輸入的是否是正整數,若是則執行循環,若不是提示輸入正整數並退出 if [[ $num =~ ^[1-9][0-9]{0,}$ ]] ; then for i in {1..$num};do #for i in `seq 1 $num`;do let sum+=$i #sum=$[$sum+$i] 這種方式也可以不過不夠簡練 done else echo "Error : please input a positive integer" && exit 2 fi #顯示最後的和 echo "The sum is : $sum"
下面執行該腳本
[root@docker hmworks]# sh 0906-2 Please inset a number :8 0906-2:行14: let: sum+={1..8}: 語法錯誤: 期待操作數 (錯誤符號是 "{1..8}") The sum is : 0
該結果說明{start..end}形式不適用於有變量出現的情況,既然這個不行就來試試$(seq start [[step]end])
#!/bin/bash #sum “1+2+...+n” #author chawan #date:20160906 declare -i sum=0 #以交互的方式輸入一個正整數 read -p "Please inset a number :" num #判斷輸入的數是否為空,為空則提示並退出 [ -z $num ] && echo "Please input a number!" && exit 1 #判斷輸入的是否是正整數,若是則執行循環,若不是提示輸入正整數並退出 if [[ $num =~ ^[1-9][0-9]{0,}$ ]] ; then for i in `seq 1 $num`;do let sum+=$i #sum=$[$sum+$i] done else echo "Error : please input a positive integer" && exit 2 fi #顯示最後的和 echo "The sum is : $sum"
執行該腳本
[root@docker hmworks]# sh 0906-2 Please inset a number :10 The sum is : 55 [root@docker hmworks]# sh 0906-2 Please inset a number :100 The sum is : 5050
該結果表明$(seq start [[step]end])適用性更好,因此一般建議使用它。
列表的glob與命令這兩種就不再具體演示。大家感興趣可以自己嘗試下做個實驗體會體會。
………………………………………………………………………………………………………………………
while循環
while語句使用格式:
while CONDITION; do
循環體
done
CONDITION:循環控制條件;進入循環之前,先做一次判斷;每一次循環之後會再次做判斷;條件為“true”,則執行一次循環;直到條件測試狀態為“false”終止循環;
因此:CONDTION一般應該有循環控制變量;而此變量的值會在循環體不斷地被修正;
進入條件:CONDITION為true;
退出條件:CONDITION為false
………………………………………………………………………………………………………………………
示例:計算1+2+...+10的值
#!/bin/bash #sum the value of "1+2+...+10" while #author chawan #date:20160906 #為了嚴謹起見,事先聲明變量sum及i為整數型 declare -i sum=0 declare -i i=1 while [ $i -le 10 ];do let sum+=$i #sum=$[$sum+$i]的簡寫形式 let i++ #不斷修正變量體 done echo "The sum is : $sum"
執行腳本,查看其是否正確執行
[root@docker hmworks]# sh 0906-3 The sum is : 55
while與for的不同在於:
1、不需要列表,因此可以大大節省內存空間,因為for如果列表很大會占用較多內容空間,對系統性能會造成影響,所以此時while的優越性就顯現出來,它不需要占用很多內存空間,只需要兩個變量的空間及做加法即可。
2、while需要修正體來不斷修正變量,最終在符合退出條件時結束循環。
………………………………………………………………………………………………………………………
until循環
until語句使用格式:
until CONDITION; do
循環體
done
CONDITION:循環控制條件;進入循環之前,先做一次判斷;每一次循環之後會再次做判斷;條件為“false”,則執行一次循環;直到條件測試狀態為“true”終止循環;
因此:CONDTION一般應該有循環控制變量;而此變量的值會在循環體不斷地被修正;
進入條件:CONDITION為false;
退出條件:CONDITION為true
until的用法同while,唯一的區別在於進入循環與退出循環的條件相反。
以相同的例子來體會二者的區別
………………………………………………………………………………………………………………………
示例:計算1+2+...+10的值
#!/bin/bash #sum the value of "1+2+...+10" until #author chawan #date:20160906 declare -i sum=0 declare -i i=1 until [ $i -gt 10 ];do let sum+=$i let i++ done echo "The sum is : $sum"
執行腳本,查看結果是否正確輸出
[root@docker hmworks]# sh 0906-4 The sum is : 55
通過比較while與until的唯一差別就在於判斷條件。這兩者其實算是同一種循環語句,只是進入及退出循環的條件正好相反。
循環控制語句(用於循環體中)
1、continue [N]:提前結束第N層的本輪循環,而直接進入下一輪判斷;
其使用格式:
while CONDTIITON1; do
CMD1
...
if CONDITION2; then
continue
fi
CMDn
...
done
………………………………………………………………………………………………………………………
示例:求100以內所有偶數之和;要求循環遍歷100以內的所正整數
#!/bin/bash #求100以內所有偶數之和;要求循環遍歷100以內的所正整數 #author chawan #date:20160906 declare -i i=1 declare -i sum=0 while [ $i -le 100 ];do let i++ #如果為奇數則跳過該循環 if [ $[${i}%2] -eq 1 ];then continue fi let sum+=$i done echo "The even number sum : $sum"
執行腳本,查看結果是否正確顯示
[root@docker hmworks]# sh 0906-5 The even number sum : 2550
之前我寫這個腳本時是這麽寫的
#!/bin/bash #求100以內所有偶數之和;要求循環遍歷100以內的所正整數 #author chawan #date:20160906 declare -i i=1 declare -i sum=0 while [ $i -le 100 ];do let sum+=$i #如果為奇數則跳過該循環,直接進入下一輪判斷後面的程序不再執行 if [ $[${i}%2] -eq 1 ];then continue fi let i++ done echo "The even number sum : $sum"
這就是我個人由於對continue的理解不夠準確而造成的死循環。
由於continue是跳過其所在循環,直接進入下一輪判斷,後面的語句都不再執行。
當時沒註意這點所以錯誤地把i++放在後面,這就導致若i起始值為奇數那麽它就一直在重復執行。
這裏只要將let sum+=$i與let i++調換為止即可正確執行。
………………………………………………………………………………………………………………………
2、break [N]:提前結束循環;
其使用格式:
while CONDTIITON1; do
CMD1
...
if CONDITION2; then
break
fi
CMDn
...
done
break的使用通常是與死循環同時出現的,下面來介紹如何創建死循環
創建死循環:
while true; do
循環體
done
until false; do
循環體
done
………………………………………………………………………………………………………………………
示例:每隔3秒鐘到系統上獲取已經登錄的用戶的信息;如果docker登錄了,則記錄於日誌中,並退出;
#!/bin/bash #每隔3秒鐘到系統上獲取已經登錄的用戶的信息;如果docker用戶登錄,則記錄於日誌中,並退出腳本 #author chawan #date:20160906 while true;do if who | grep "^docker\>" $> /dev/null;then break fi sleep 3 echo "docker is not login" done echo "docker logged on." >> /tmp/user.log
運行腳本
[root@docker hmworks]# sh 0906-6 docker is not login docker is not login docker is not login docker is not login docker is not login docker is not login
為了驗證該腳本,下面我們使用docker用戶登陸
docker用戶登陸後查看/tmp/user.log文件
循環語句的特殊用法(while及for)
while循環的特殊用法(遍歷文件的每一行):
其使用格式:
while read line; do
循環體
done < /PATH/FROM/SOMEFILE
依次讀取/PATH/FROM/SOMEFILE文件中的每一行,且將行賦值給變量line
………………………………………………………………………………………………………………………
示例:找出其ID號為偶數的所有用戶,顯示其用戶名及ID號;
#!/bin/bash #找出其ID號為偶數的所有用戶,顯示其用戶名及ID號 #author chawan #date:20160906 while read line;do if [ $[`echo $line | cut -d: -f3`%2] -eq 0 ];then echo -e -n "username: `echo $line|cut -d: -f1`\t" echo "uid:`echo $line|cut -d: -f3`" fi done < /etc/passwd
運行腳本
………………………………………………………………………………………………………………………
for循環的特殊格式:
for ((控制變量初始化;條件判斷表達式;控制變量的修正表達式)); do
循環體
done
控制變量初始化:僅在運行到循環代碼段時執行一次;
條件判斷表達式:在什麽條件下進行循環;
控制變量的修正表達式:每輪循環結束會先進行控制變量修正運算,而後再做條件判斷;
示例:求100以內所正整數之和
#!/bin/bash #求100以內所正整數之和 #author chawan #date:20160906 declare -i sum=0 for ((i=1;i<=100;i++));do let sum+=$i done echo "The sum is : $sum"
運行腳本,查看結果是否正確
[root@docker hmworks]# sh 0906-8 The sum is : 5050
for的這種格式減少了代碼量,看著更簡潔,不過其限制是只適用於有數字出現的循環,若是對某目錄下的所有文件進行某種循環的執行就不適應了。
循環嵌套
在本文的最後再以一題體會下循環嵌套的神奇
示例:打印九九乘法表
#!/bin/bash #打印九九乘法表 #author chawan #date : 20160906 for((j=1;j<=9;j++));do for((i=1;i<=j;i++))do echo -e -n "${i}X${j}=$[$i*$j]\t" done echo done
我在剛剛接觸循環嵌套時各種暈,循環嵌套不是沒有目的的亂用,而是根據自己的需求有目的的使用,比如要打印99乘法表,首先要分析99乘法表的規律,首先它橫行是連續的,通常在遇到連續的內容都會用到循環,再觀察我們發現它的列也是連續的,因此又用到一個循環,而99乘法表又是由兩個變化的量構成,綜上我們就可以確定,需要使用兩個變量,這兩個變量分別要用到循環,而一個變量又受到另一個變量的限制,因此這個受限的變量就是被嵌套的主。問題分析到這裏,我們解決這個問題要用到的工具都找出來了,下面就是靠自己去使用工具解決問題了。我相信大家這點應該都不成問題,問題就分析到這裏。
小結:
本文主要介紹什麽是循環,死循環,bash常用的三種循環語句for、while、until及循環控制語句continue、break
在本文結尾又介紹了while的特殊用法(遍歷文件中的每一行),for的C語言格式。
至於什麽時候用for什麽時候用while需要自己在實際寫腳本中細細比較,鑒於本人也是新手,這裏就算想細說也只能望洋興嘆。
本文出自 “張帆-IT的奇幻漂流” 博客,請務必保留此出處http://chawan.blog.51cto.com/9179874/1847024
Tags: 程序員 Linux start 如何 影響
文章來源: