標籤:fan cti curl tps poj exp 迴圈 sum lse
1.break、continue、exit、return的區別
break、continue在條件陳述式及迴圈語句(for、while、if等)中用於控製程序的走向;而exit則用於終止所有語句並退出當前指令碼了,除此之外exit還可以返回上一次程式或命令的執行狀態值給當前shell;ruturn和exit類似,只不過return用於在函數內部返回函數執行的狀態值。基本說明如所示:
2.break、continue、exit功能執行流程圖
以while迴圈和for迴圈舉例。break功能執行流程圖如所示:
continue功能執行流程圖如下所示:
exit功能的執行流程圖如所示:
3.break、continue、exit、return命令樣本
範例:通過下面的指令碼驗證break、continue、exit、return命令的功能
[[email protected] jiaobenlianxi]# cat xunhuankongzhi.sh#!/bin/bashif [ $# -ne 1 ];then 如果參數不為執行if語句裡面的echo命令echo $"Usage:$0 {break|continue|exit|return}" 分別傳入4個命令作為參數exit 1 退出指令碼fifunction test(){ 定義測試函數for((i=0;i<=5;i++))doif [ $i -eq 3 ];then$*; 用於接收函數體外的參數fiecho $idoneecho "I am in func." 執行for迴圈外的輸出提示}test $* 調用test函數,實現指令碼傳參func_ret=$? 接收並測試函數的傳回值if [ `echo $*|grep return|wc -l` -eq 1 ] 如果傳參是return執行難,if語句中echo命令thenecho "return‘s exit status:$func_ret" 如果傳參是return,列印函數的傳回值fiecho "ok" 函數體外的輸出提示
(1)驗證break命令,執行結果如下
[[email protected] jiaobenlianxi]# sh xunhuankongzhi.sh Usage:xunhuankongzhi.sh {break|continue|exit|return}[[email protected] jiaobenlianxi]# sh xunhuankongzhi.sh break012I am in func.ok
從結果可以看出,當i=3時執行了break命令迴圈中以後的命令沒有執行,但是迴圈外的echo命令執行了,執行到break時跳出了if以及for迴圈,然後執行test函數中的echo命令以及test函數體外的echo命令。
(2)驗證continue命令,執行結果如下
[[email protected] jiaobenlianxi]# sh xunhuankongzhi.sh continue01245I am in func.ok
可以看出當i=3時,這層迴圈沒有被執行,其他迴圈全部還行了,迴圈外的echo也執行了,這說明執行到continue時,終止(跳出)了本次迴圈,而繼續下一次的迴圈,直到迴圈正常結束,接著執行迴圈外的所有語句。
(3)驗證exit命令,在下一個shell裡可以用“$?”接收exit n的傳回值,執行結果如下:
[[email protected] jiaobenlianxi]# sh xunhuankongzhi.sh "exit 100"012[[email protected] jiaobenlianxi]# echo $?100
從結果可以看出,當進入迴圈裡的if語句後遇到“exit 100”時,立刻腿出程式;不但迴圈體3後面的數字沒有輸出,而且for迴圈體done外的echo和函數外的ok也沒有輸出,就直接退出了程式。另外因為程式退出時指定100,所以執行指令碼後用“$?”擷取傳回值就返回了100。
(4)驗證return命令,執行結果如下
[[email protected] jiaobenlianxi]# sh xunhuankongzhi.sh "return 100"012return‘s exit status:100ok[[email protected] jiaobenlianxi]# echo $?0
當執行到return 100時,就沒有執行3一下的數字,說明return跳出了迴圈體、for迴圈體done後echo也沒有執行而是直接執行後函數體外面的內容,可以看出return的作用是退出當前函數。同return將數字100作為函數的傳回值返回給函數體外,傳回值$func_ret的值等於100。執行指令碼後列印的傳回值是0,因為程式左後列印的是echo命令,執行成功,多以執行指令碼最後傳回值是0。
4.案例
(1)案例1:開發shell指令碼實現為伺服器臨時配置多個IP,並且不能臨時撤銷配置的所有IP,IP位址範圍為:192.168.136.220-192.168.136.225,其中192.168.136.223不能設定。
使用ifconfig給IP設定別名:
ifconfig eth0:0 192.168.136.224/24 up 添加別名ifconfig eth0:0 192.168.136.224/24 down 刪除別名
使用ip addr給IP設定別名:
ip addr add 192.168.136.224/24 dev eth0 label eth0:0 添加別名ip addr del 192.168.136.224/24 dev eth0 label eth0:0 刪除別名
代碼如下:
[[email protected] jiaobenlianxi]# cat ipalias.sh #!/bin/bash[ -f "/etc/init.d/functions" ] && . /etc/init.d/functionsRETVAL=0export PATH="/usr/local/mysql/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/curl/bin:/root/bin"function add(){for ip in {220..225}doif [ $ip -eq 223 ];thencontinuefiip addr add 192.168.136.$ip/24 dev eth0 label eth0:$ip &>/dev/nullRETVAL=$?if [ $RETVAL -eq 0 ];thenaction "add $ip" /bin/trueelseaction "add $ip" /bin/falsefidonereturn $RETVAL}function del(){for ip in {225..220}do if [ $ip -eq 223 ];thencontinue fiip addr del 192.168.136.$ip/24 dev eth0 label eth0:$ip &>/dev/nullRETVAL=$?if [ $RETVAL -eq 0 ];thenaction "del $ip" /bin/trueelseaction "del $ip" /bin/falsefidonereturn $RETVAL}function main(){case "$1" instart) add RETVAL=$? ;; stop) del RETVAL=$? ;; restart) del sleep 2 add RETVAL=$? ;;*) printf "Usage:$0 {start|stop|restart}\n"esac}main $1exit $RETVAL
(2)案例2:分析apache訪問日誌,把日誌中每行的訪問位元組數對應的欄位數相加,計算出訪問量。用while迴圈實現。朋友們做測試的時候如果沒有訪問日誌可以去網上下載一個訪問日誌。
[[email protected] jiaobenlianxi]# cat apachefangwen.sh #!/bin/bashsum=0RETVAL=0byte="1024"b="/home/linzhongniao/tools/access_2013_05_30.log"exec <$bwhile read line do size=`echo $line|awk ‘{print $10}‘|grep -v "-"|tr ‘\r‘ ‘ ‘` expr $size + 1 &>/dev/null if [ $? -ne $RETVAL ];thencontinue fi ((sum+=size))doneecho "${b}:total:${sum}bytes = `expr ${sum} / $byte`KB"
(3)案例3:破解用RANDOM產生的隨機數“0~32767”範圍內的所有數字用md5sum加密之前的數字?
解決過程,先將0-32767範圍內的所有數字通過md5sum加密,並把加密後的字串和加密前的數字對應的寫入到記錄檔中,指令碼如下:
[[email protected] jiaobenlianxi]# cat RANDOM.sh #!/bin/bashfor n in {0..32767}doecho "`echo $n|md5sum` $n" >>/tmp/zhiwen1.logdone
查看執行結果:
[[email protected] jiaobenlianxi]# head /tmp/zhiwen.log 897316929176464ebc9ad085f31e7284 - 0b026324c6904b2a9cb4b88d6d61c81d1 - 126ab0db90d72e28ad0ba1e22ee510510 - 26d7fce9fee471194aa8b5b6e47267f03 - 348a24b70a0b376535542b996af517398 - 41dcca23355272056f04fe8bf20edfce0 - 59ae0ea9e3c9c6e1b9b6252c8395efdc1 - 684bc3da1b3e33a18e8d5e1bdd7a18d7a - 7c30f7472766d25af1dc80b3ffc9a58c7 - 87c5aba41f53293b712fd86d08ed5b36e - 9
解密加密後的字串3ae5dc2d,和指紋庫裡面的所有使用md5sum加密後的字串進行比對,如果匹配輸出加密之前的數字。
[[email protected] jiaobenlianxi]# cat md5pojie.sh #!/bin/bash#for n in {0..32767}#do# echo "`echo $n|md5sum` $n" >>/tmp/zhiwen.log#doneexec </tmp/zhiwen.logmd5char="3ae5dc2d"while read linedo if [ `echo "$line"|grep "$md5char"|wc -l` -eq 1 ];then echo "$line" break fidone
執行結果:3ae5dc2d加密之前的數字為10000
[[email protected] jiaobenlianxi]# sh md5pojie.sh 154773ae5dc2d36d8b9747e5d3dbfc36 - 10000
迴圈控制及狀態傳回值