Shell編程中循環命令用於特定條件下決定某些語句重複執行的控制方式,有三種經常使用的循環語句:for、while和until。while循環和for循環屬於「當型循環」,而until屬於「直到型循環」。循環控制符:break和continue控制流程轉向。html
while循環用於不斷執行一系列命令,也用於從輸入文件中讀取數據,其格式爲:shell
//while 命令 do 命令1 命令2 . . . done
雖然一般只使用一個命令,但在 while和do之間能夠放幾個命令。命令一般用做測試條
件。
只有當命令的退出狀態爲 0時,do和done之間命令才被執行,若是退出狀態不是 0,則循
環終止。
命令執行完畢,控制返回循環頂部,從頭開始直至測試條件爲假。express
實例編程
#!/bin/bash # Program: # This program will show the use of if # History: # 2015/1/8 Alex First release i=10 while [[ $i -gt 5 ]] do echo $i i=`expr $i - 1`; done exit 0
注意:在Shell中四則運算不能簡簡單單的加減乘除,應該要寫以下的格式: val1=`$val2 - 1` 其中「=」後面用「`」包住表達式,這個符號在Shell中十分有用,是Tab鍵上面「~」的原來形式。能夠用來將不少命令的結果保存到一個變量中去。接着就是運算符了,運算符的左右兩邊必須是空格,不然會出錯。
deyuy/bin/my_shell >> ./while1.sh 10 9 8 7 6
注意: 1.expr命令的用法請參考 http://blog.chinaunix.net/uid-25880122-id-2937521.html 2.``的做用是運行``之間的命令,而且將命令運行的結果返回。詳細請參考:http://blog.csdn.net/miyatang/article/details/8077123 3. 更多while實例參考:http://blog.csdn.net/firefoxbug/article/details/7237319
until循環執行一系列命令直至條件爲真時中止。 until循環與while循環在處理方式上恰好相反。通常while循環優於until循環,但在某些時候—也只是極少數狀況下, until循環更加有用。vim
//until循環格式爲: until 條件 命令1 . . . done
條件可爲任意測試條件,測試發生在循環末尾,所以循環至少執行一次—請注意這一
點。bash
until循環中,只要條件不爲真,就執行do和done之間的循環命令,或者說,在until循環中,一直執行do和done之間的循環命令,直到條件爲真;服務器
–避免生成死循環。 app
# Program: # This program will show the use of until # History: # 2015/1/13 Alex First release sum=0 num=10 until test $num -eq 0 do sum=`expr $sum + $num` num=`expr $num - 1` done echo "sum = $sum" exit 0 deyuy/bin/my_shell >> sh until.sh sum = 55
//for循環通常格式爲: for 變量名i n列表 do 命令1 命令2… done
當變量值在列表裏, for循環即執行一次全部命令,使用變量名訪問列表中取值。命令可爲任何有效的shell命令和語句。
變量名爲任何單詞。 in列表用法是可選的,若是不用它, for循環使用命令行的位置參數。
in列表能夠包含替換、字符串和文件名,列表能夠自定義,也能夠經過命令返回值生成,下面是一些經常使用例子。oop
#!/bin/bash # Program: # This program will show the use of for # History: # 2015/1/12 First release # 自定義列表 for loop in 1 2 3 4 5 do echo "loop=$loop" done exit 0 deyuy/bin/my_shell >> chmod u+x for1.sh deyuy/bin/my_shell >> ./for1.sh loop=1 loop=2 loop=3 loop=4 loop=5 //還能夠經過讀取文件內容生成變量列表 deyuy/bin/my_shell >> vim num.txt 1 2 3 4 5 6 7 8 #!/bin/bash # Program: # This program will show the use of for # History: # 2015/1/12 First release # 以命令返回值做爲列表 i=0 for i in `cat num.txt` do echo "i=$i" done exit 0 deyuy/bin/my_shell >> ./for1.sh i=1 i=2 i=3 i=4 i=5 i=6 i=7 i=8
#!/bin/bash # Program: # This program will show the use of for # History: # 2015/1/12 First release # 自定義列表:帶引號 i=0 for loop in "apple hhhh bbbb eeee" do i=`expr $i + 1` echo "loop=$loop" echo "count=$i" done exit 0 deyuy/bin/my_shell >> chmod u+x for4.sh deyuy/bin/my_shell >> ./for4.sh loop=apple hhhh bbbb eeee count=1 *說明:從結果能夠看出for循環打印字符串到結束,包括空格,只執行了一次。若是把 in列表改成 for loop in "apple" "hhhh" "bbbb" "eeee" 則輸出結果爲 loop=apple count=1 loop=hhhh count=2 loop=bbbb count=3 loop=eeee count=4
#!/bin/bash # Program: # This program will show the use of for # History: # 2015/1/12 First release # 自定義列表,不帶引號 i=0 for loop in apple hhhh bbbb eeeedo i=`expr $i + 1` echo "loop=$loop" echo "count=$i" done exit 0 deyuy/bin/my_shell >> ./for4.sh loop=apple count=1 loop=hhhh count=2 loop=bbbb count=3 loop=eeee count=4
注意:對比兩張方式輸出的不一樣能夠看出,若是用戶想讓把空格分割的每一個單詞都輸出要經過第二種方式。測試
# Program: # This program will show the use of for # History: # 2015/1/12 First release for loop in `ls` do echo "$loop" done exit 0 deyuy/bin/my_shell >> sh for2.sh app1 for1.sh for2.sh fun1.sh hello.sh hh.sh if.sh if2.sh test.sh test2.sh var.sh while1.sh
#!/bin/bash # Program: # This program will show the use of for # 統計當前目錄下文件數 # History: # 2015/1/12 First release counter=0 for files in * do counter=`expr $counter + 1` done echo "There are $counter files in `pwd` directory." exit 0 deyuy/bin/my_shell >> sh for3.sh There are 13 files in /home/deyuy/bin/my_shell directory.
#!/bin/bash # Program: # This program will show the use of for # History: # 2015/1/13 release i=0 for params do i=`expr $i + 1` echo "You supplied $params as a command line option" echo "count=$i" done echo $params exit 0 deyuy/bin/my_shell >> ./for5.sh p1 p2 p3 You supplied p1 as a command line option count=1 You supplied p2 as a command line option count=2 You supplied p3 as a command line option count=3 p3 ###下面的腳本包含i n"$ @",結果與上面的腳本相同。 #!/bin/bash # Program: # This program will show the use of for # History: # 2015/1/13 release i=0 for params in "$@" do i=`expr $i + 1` echo "You supplied $params as a command line option" echo "count=$i" done echo $params exit 0 deyuy/bin/my_shell >> ./for5.sh p1 p2 p3 You supplied p1 as a command line option count=1 You supplied p2 as a command line option count=2 You supplied p3 as a command line option count=3 p3 ###下面的腳本包含i n"$ *",結果與上面的腳本不一樣。 #!/bin/bash # Program: # This program will show the use of for # History: # 2015/1/13 release i=0 for params in "$*" do i=`expr $i + 1` echo "You supplied $params as a command line option" echo "count=$i" done echo $params exit 0 deyuy/bin/my_shell >> ./for5.sh p1 p2 p3 You supplied p1 p2 p3 as a command line option count=1 p1 p2 p3
說明:關於$@和$*的區別請參考http://www.cnblogs.com/yuexiaxiaoxi/articles/4203609.html
嵌入循環能夠將一個f o r循環嵌在另外一個f o r循環內:
for 變量名1 in列表1 do for 變量名2 in 列表2 do 命令1 . . . done done
下面腳本即爲嵌入for循環,這裏有兩個列表apps和scripts。第一個包含服務器上應用
的路徑,第二個爲運行在每一個應用上的管理腳本。對列表 apps上的每個應用,列表
scripts裏的腳本將被運行,腳本實際上爲後臺運行。腳本使用tee命令在登陸文件上放一條
目,所以輸出到屏幕的同時也輸出到一個文件。查看輸出結果就能夠看出嵌入for循環怎樣使
用列表scripts以執行列表apps上的處理。
#!/bin/bash # Program: # This program will show the use of for # History: # 2015/1/13 release APPS="/apps/accts /apps/claims /apps/stock /apps/serv" SCRIPTS="audit.check report.run cleanup" MY_DATE=`date +%H:%M" on "%d/%m/%Y` i=0 j=0 #outer loop for loop in $APPS do i=`expr $i + 1` #inner loop for loop2 in $SCRIPTS do j=`expr $i + 1` echo "system $loop now running $loop2 at $MY_DATE" echo "inner loop counter=$j" done echo "outer loop counter=$i" done echo $params deyuy/bin/my_shell >> ./for6.sh system /apps/accts now running audit.check at 20:53 on 12/01/2015 inner loop counter=2 system /apps/accts now running report.run at 20:53 on 12/01/2015 inner loop counter=2 system /apps/accts now running cleanup at 20:53 on 12/01/2015 inner loop counter=2 outer loop counter=1 system /apps/claims now running audit.check at 20:53 on 12/01/2015 inner loop counter=3 system /apps/claims now running report.run at 20:53 on 12/01/2015 inner loop counter=3 system /apps/claims now running cleanup at 20:53 on 12/01/2015 inner loop counter=3 outer loop counter=2 system /apps/stock now running audit.check at 20:53 on 12/01/2015 inner loop counter=4 system /apps/stock now running report.run at 20:53 on 12/01/2015 inner loop counter=4 system /apps/stock now running cleanup at 20:53 on 12/01/2015 inner loop counter=4 outer loop counter=3 system /apps/serv now running audit.check at 20:53 on 12/01/2015 inner loop counter=5 system /apps/serv now running report.run at 20:53 on 12/01/2015 inner loop counter=5 system /apps/serv now running cleanup at 20:53 on 12/01/2015 inner loop counter=5 outer loop counter=4
case語句爲多選擇語句。能夠用 case語句匹配一個值與一個模式,若是匹配成功,執行相
匹配的命令。case語句格式以下:
case expression in pattern1 ) statements ;; pattern2 ) statements ;; ... esac
case工做方式如上所示。取值後面必須爲單詞 i n,每一模式必須以右括號結束。取值能夠
爲變量或常數。匹配發現取值符合某一模式後,其間全部命令開始執行直至;;。
取值將檢測匹配的每個模式。一旦模式匹配,則執行完匹配模式相應命令後再也不繼續
其餘模式。若是無一匹配模式,使用星號 *捕獲該值,再接受其餘輸入。
模式部分可能包括元字符,與在命令行文件擴展名例子中使用過的匹配模式類型相同,
即:
* 任意字符。
? 任意單字符。
[..] 類或範圍中任意字符。
注意:
1.模式字符串中可使用通配符
2.若是一個模式字符串中包含多個模式,那麼各模式之間應以豎線(|)隔開,表各模式是「或」的關係,即只要給定字符串與其中一個模式相配,就會執行其後的命令列表。
3.各模式字符串應是惟一的,不該重複出現,而且要合理安排它們的出現順序,例如,不該將「*」做爲頭一個模式字符串,由於「*」能夠與任何字符串匹配,若第一個出現,就不會再檢查其餘模式了。
4.case語句以關鍵字case開頭,以關鍵字esac結束。
5.case的退出(返回)值是整個結構中最後執行的命令的退出值。若沒有執行任何命令,則退出值爲0.
#!/bin/bash # Program: # This program will show the use of for # History: # 2015/1/13 First release case $1 in y|Y) echo "your choice is yes";; n|N) echo "your choice is no";; *) echo "your choice is others";; esac exit 0 deyuy/bin/my_shell >> chmod u+x case.sh deyuy/bin/my_shell >> ./case.sh y your choice is yes deyuy/bin/my_shell >> ./case.sh n your choice is no deyuy/bin/my_shell >> ./case.sh jjjj your choice is others
格式:
select 變量 in 列表 do 命令行(一般用到循環變量) done
製做一個選擇表,在列表中選擇一個選項執行命令行。若是選擇的變量不在列表序列中,則返回一個空值。須要用break退出循環。
#!/bin/bash # Program: # This program will show the use of for # History: # 2015/1/13 First release echo "a is 5 ,b is 3. Please select your method: " a=5 b=3 select var in "a+b" "a-b" "a*b" "a/b" do break done case $var in "a+b") echo 'a+b= '`expr $a + $b`;; "a-b") echo 'a-b= '`expr $a - $b`;; "a*b") echo 'a*b= '`expr $a \* $b`;; "a/b") echo 'a/b= '`expr $a / $b`;; *) echo "input error" esac deyuy/bin/my_shell >> chmod u+x select.sh deyuy/bin/my_shell >> ./select.sh a is 5 ,b is 3. Please select your method: 1) a+b 2) a-b 3) a*b 4) a/b #? 3 a*b= 15
–一、break:用於當即終止當前循環的執行,break命令可使用戶從循環體中退出來。
–語法:break[n] ,其中,n表示要跳出幾層循環,默認值爲1
#!/bin/bash for var1 in 1 2 3 do for var2 in 0 5 do if [ $var1 -eq 2 -a $var2 -eq 0 ] then break 2 else echo "$var1 $var2" fi done done
運行結果:
1 0
1 5
–二、continue:跳過循環體中在其以後的語句,會返回到本循環層的開頭,進行下一次循環。
–語法:continue[n],其中,n表示從包含continue語句的最內層循環體向外跳到第幾層循環,默認值爲1,循環層數是由內向外編號。
#!/bin/bash NUMS="1 2 3 4 5 6 7" for NUM in $NUMS do Q=`expr $NUM % 2` if [ $Q -eq 0 ] then echo "Number is an even number!!" continue fi echo "Found odd number" done
運行結果:
Found odd number Number is an even number!! Found odd number Number is an even number!! Found odd number Number is an even number!! Found odd number