shell腳本編程學習之路-while循環

1.當型循環和直到型循環

while循環使用的很少,通常守護進程程序或始終循環執行會用到,其餘循環運算都用for循環代替。shell

1.1 當型和直到型循環語法

(1)while條件語句 apache

while <條件表達式> 

do

      指令….

done

while循環執行流程對應的邏輯圖如圖1-1所示:編程

shell腳本編程學習之路-while循環

(2)until條件語句 bash

until <條件表達式> 

do

      指令…

Done

提示:只循環一次,應用場景很少,瞭解就好。ide

1.2 當型和直到型循環基本範例

執行掛起一段時間:sleep1掛起秒,usleep1000000掛起1秒。達到一分鐘一次執行腳本就就用定時任務。 函數

1.2.1 範例1:每隔2秒記錄一次系統負載狀況

方法一:每隔2秒屏幕輸出負載值學習

[root@shellbiancheng jiaobenlianxi]# cat while1.sh 
#!/bin/sh
while true
   do
    uptime
    sleep 2
   done

提示:while true 表示條件永遠爲真,所以會一直執行,像死循環同樣,咱們稱之爲守護進程。測試

執行結果以下:日誌

[root@shellbiancheng jiaobenlianxi]# sh while1.sh 
 02:50:13 up 1 day, 11:47,  3 users,  load average: 0.00, 0.00, 0.00
 02:50:15 up 1 day, 11:47,  3 users,  load average: 0.00, 0.00, 0.00

方法二:追加到log日誌文件裏code

[root@shellbiancheng jiaobenlianxi]# cat while2.sh 
#!/bin/sh
while [ 1 ]  注意[]中括號兩端有空格,true和1都表示條件永久成立
   do
    uptime >>./uptime.log
    sleep 2
   done
[root@shellbiancheng jiaobenlianxi]# tail -f uptime.log 
 03:00:24 up 1 day, 11:57,  3 users,  load average: 0.01, 0.01, 0.00
 03:00:26 up 1 day, 11:57,  3 users,  load average: 0.01, 0.01, 0.00

經過在腳本的結尾使用&符號來在後臺運行腳本:

[root@shellbiancheng jiaobenlianxi]# sh while2.sh &

[1] 3991

提示:在後臺永久執行,咱們稱之爲守護進程模式。

防止客戶端執行腳本中斷,在後臺永久執行的方法:

(1)sh while2.sh & 加&符號,讓腳本在後臺執行

(2)nohup while2.sh & 用戶退出以後繼續執行腳本

(3)screen 保持會話

1.2.2 讓腳本在後臺運行知識

shell腳本編程學習之路-while循環

擴展:

bg: 後臺運行

fg: 掛起程序

jobs: 顯示後臺程序

kill(kill %1),killall,pkill: 殺掉進程

crontab:設置定時

ps: 查看進程

pstree: 顯示進程

nice: 改變優先級

nohup:用戶退出系統以後繼續工做

pgrep:查找匹配條件的進程

strace:跟蹤一個進程的系統調用狀況,若是在工做中某個進程使用率太高能夠用strace查看進程系統調用狀況,

ltrace:跟蹤進程調用庫函數的狀況。

vmstat:報告虛擬內存統計信息。

1.3 簡單範例

1.3.1 範例1:經過while語句計算從1加到100的和,請用累加的方法

[root@shellbiancheng jiaobenlianxi]# cat 1-100.sh 
#!/bin/sh
sum=0
i=1
while [ $i -le 100 ]
do
 ((sum=sum+i))
 ((i++))
done
echo $sum

1.3.2 範例2:下面經過數學公式計算的結果

[root@shellbiancheng jiaobenlianxi]# cat sum1-100.sh 
#!/bin/sh
i=100
((sum=i*(i+1)/2))
echo $sum

1.3.3 範例3:手機充值

手機充值10元,每發一次短信(輸出當前餘額)花費1角5分錢,當餘額低於1角5分錢不能發短信,提示餘額不足,請充值(能夠容許用戶繼續充值繼續發短信),請用while語句實現。

提示:單位換算,統一單位,統一成整數。10元=1000分,1角5分=15分

[root@shellbiancheng jiaobenlianxi]# cat huafei.sh 
#!/bin/bash
HUAFEI=100
YUE=25
if [ -f /etc/init.d/functions  ];then
    . /etc/init.d/functions
fi
OPTION() {
case "$option" in
    [yY]|[yY][eE][sS])
        echo "Send a success"
        echo $txt >>/var/log/consum.log
        ((HUAFEI=HUAFEI-YUE))
        echo "You're still saving money $HUAFEI"
        ;;
    [nN]|[nN][oO])
        echo "Abort send, succeed."
        ;;
        *)
        echo "Input error"
        ;;
esac
    return 0
}

CHANGE1() {
    expr $change + 1 &>/dev/null
    if [ "$?" -ne "0" -a "$change" != "-1" ];then
        echo "There are illegal characters, please reenter the amount of recharge."
    else
    break
    fi
    return 0
}

CHANGE() {
while true
do
read -p "Please input the amount you want to recharge:" change
CHANGE1
done
return 0
}

CHANGE2() {

((HUAFEI+=change))
echo "You're still saving money $HUAFEI"

}

OPTION2() {
case "$option2" in
    [yY]|[yY][eE][sS])
        CHANGE
        CHANGE2
        ;;
    [nN]|[nN][oO])
        exit 1
        ;;
        *)
        echo "Input error, please enter the correct amount."
         CHANGE
         CHANGE2
        ;;
esac
return 0
}

linzhongniao() {

if [ "$HUAFEI" -lt "$YUE" ];then
    read -p "The balance is insufficient, please recharge[y|n]" option2
    OPTION2
fi
return 0
}

main() {
while [ "$HUAFEI" -ge "$YUE" ]
do
read -p "Please enter the content of the text message:" txt
read -p "Confirm send [y|n]" option

OPTION
linzhongniao
done
return 0
}
main

1.4 擴展

while按行讀文件的方式

1.4.1 方法一:採用exec讀取文件方式

[root@shellbiancheng jiaobenlianxi]# cat while_duwenjian1.sh 
#!/bin/bash
i=/home/linzhongniao/tools/access.log
exec<$i
while read line
 do
echo $line
 done

1.4.2 方法二:採用cat讀取文件方式

[root@shellbiancheng jiaobenlianxi]# cat while_duwenjian2.sh 
#!/bin/bash
i=/home/linzhongniao/tools/access.log 
cat $i|while read line
do
echo $line
done

1.4.3 方法三:在while循環結尾處重定向文件

[root@shellbiancheng jiaobenlianxi]# cat while_duwenjian3.sh 
#!/bin/bash
i=/home/linzhongniao/tools/access.log
 while read line
 do
echo $line
 done<$i

1.4.4 問題分析apache日誌例子

分析apache訪問日誌,把日誌中每行的訪問字節數對應的字段數相加,計算出訪問量。用while循環實現。朋友們作測試的時候若是沒有訪問日誌能夠去網上下載一個訪問日誌。

[root@shellbiancheng tools]# wc -l access_2013_05_30.log 
548160 access_2013_05_30.log    
[root@shellbiancheng jiaobenlianxi]# cat apachefangwen.sh
#!/bin/bash
sum=0
RETVAL=0
byte="1024"
b="/home/linzhongniao/tools/access_2013_05_30.log"
exec <$b
while read line 
do
   size=`echo  $line|awk '{print $10}'|grep -v "-"|tr '\r' '  '`  
   expr $size + 1 &>/dev/null
   if [ $? -ne 0 ];then
   ((sum+=size))    
   fi
done
echo "${b}:total:${sum}bytes = `expr ${sum} / $byte`KB"

在作計算的地方出現了點問題,修改以前作計算的地方是這樣寫的((sum+=$size)),處理小文件還行處理大文件的時候就會報錯(個人測試文本有54萬行),在網上查詢了緣由是在$取值的時候括號裏面只須要跟變量便可(變量可自行進行計算),不須要在對括號內進行運算的變量在進行取值操做即把括號中的$符號去掉,哎這個小問題折騰了我半天時間啊。

2.While循環小結

一、while循環的特長是執行守護進程以及咱們但願循環不退出持續執行的狀況,用於頻率小於一分鐘循環處理,其餘的while循環幾乎均可以被for循環替代。

二、case語句能夠替換if語句,通常在系統啓動腳本傳入少許固定規則字符串,用case語句。其餘普通判斷多用if語句。

三、if和for語句最經常使用,其次是while(守護進程),case(服務啓動腳本)。

各個語句的應用場景:

條件表達式,簡單的判斷(文件是否存在,字符串是否爲空等)。

if取值判斷,不一樣值數量較少的狀況。

for循環正常的循環處理,最經常使用!

while循環守護進程、無限循環(sleep)。

case服務啓動腳本,菜單。

函數邏輯清晰,減小重複語句。

相關文章
相關標籤/搜索