20160909 補充break與continue的區別程序員
什麼是循環語句、死循環?docker
循環語句:將一段代碼重複執行0、1或屢次。編程
到底要重複運行多少次?以及咱們如何設定循環語句的重複次數?bash
爲了解決上面的問題因而就有了進入條件與退出條件。ide
進入條件:條件知足時進入循環。工具
退出條件:不符合條件退出循環。性能
一種特殊的循環:死循環測試
死循環:在編程中,一個沒法靠自身的控制終止的循環稱爲"死循環"。死循環的出現有兩種狀況:ui
一、因程序須要刻意寫的;二、因程序員的失誤形成的。spa
第二種的死循環一般會形成比較嚴重的程序錯誤,甚至會所以而影響物理機。所以死循環的使用須要合理的設計。
實驗環境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的不一樣在於:
一、不須要列表,所以能夠大大節省內存空間,由於for若是列表很大會佔用較多內容空間,對系統性能會形成影響,因此此時while的優越性就顯現出來,它不須要佔用不少內存空間,只須要兩個變量的空間及作加法便可。
二、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的惟一差異就在於判斷條件。這二者其實算是同一種循環語句,只是進入及退出循環的條件正好相反。
循環控制語句(用於循環體中)
一、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++調換爲止便可正確執行。
………………………………………………………………………………………………………………………
二、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文件
#########################################################################################
break與continue語句的區別:
break語句和continue語句均可以位於各類循環體內,用於控制當前的循環流程。但,break語句是直接退出當前的循環結構,轉向執行循環體後面的語句;而continue語句則只是跳過當前循環體中continue語句後面的語句,轉向當前循環體的起始位置,從新執行下一次循環,並無退出當前的循環結構。
這是二者最本質的區別:break跳出當前循環,continue沒有跳出當前循環。
循環語句的特殊用法(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須要本身在實際寫腳本中細細比較,鑑於本人也是新手,這裏就算想細說也只能望洋興嘆。