天天看點

shell程式設計(十二)while循環

一    while循環的應用場景

while循環工作中使用的不多,一般是'守護程序'程式或'始終循環'執行場景,其它'循環計算',都會用'for替換'while
           

二    while循環的類型

當型'while'和直到'until'型循環語句
           

①  while條件句

while <條件表達式>

do

      指令 …

done

# 先判斷條件(滿足)--->執行--->判斷條件--->...
           

②  until條件句

# 不常用

until 條件

do

      指令 ...
done

# 先判斷條件(不滿足)--->執行--->判斷條件

備注: '至少'執行一次
           

三    相關指令

sleep和usleep

sleep : 執行挂起'指定'的秒數

usleep: 功能把'程序挂起'一段時間,機關是'微秒 '

'1000000us' --> '1s'

crontab: 如果是'分鐘級别'的定時任務
           

三    實踐

①  每隔兩秒列印系統的負載

#!/bin/bash
while true
do
        uptime      # 核心指令
        sleep  2    # 兩秒列印一次
done

# 可用 ctrl+c取消

# 說明: while true 表示條件永遠為真,是以為死循環會一直執行,也即守護程序!
           

②  讓腳本背景運作

#!/bin/bash
while true
do
        uptime  >> /mnt/log
        sleep 2
done

# 執行:背景運作

sh while2.sh &

# 檢測

tail -f /mnt/log

# 說明:即使把視窗關閉還是會運作

# 執行腳本,跟資料庫相關的,插入資料等,一定不要指令行輸出,放到背景執行

# 用戶端突然端了怎麼辦,執行到哪了
           

相關:防止用戶端執行腳本終端

# 防止用戶端執行腳本中斷的方法。

1、sh while.sh &                 # 通過kill -p pid 關閉

2、nohup while.sh &

# 說明:上述是開發人員常用的

3、screen保持回話 # 比較進階
           

screen指令

回憶:腳本在背景執行的相關擴充

ctl+c:停止執行目前腳本或任務

ctrl+z:暫停執行目前腳本或任務

bg:把目前腳本(前台)或任務放入背景執行

fg:目前腳本或任務進行前台執行,如果有多個任務,可以fg加任務編号調出

jobs:檢視目前執行的腳本或任務 
           

程序管理指令

# 程序管理常用16個指令

bg:背景運作

fg:挂起程式

jobs:顯示背景程式

kill、killall、pkill:殺掉程序

crontab:設定定時

ps:檢視程序

pstree:顯示程序狀态樹

top:顯示程序

nice:改變優先權

nohup:使用者退出系統之後繼續工作

pgrep:查找比對條件的程序

strace:跟蹤一個程序的系統調用情況(strace + pid)

ltrace:跟蹤程序調用庫函數的情況

vmstat:報告虛拟記憶體統計資訊 
           

③  while實作1到100之和

#!/bin/bash
i=1;sum=0
while [ $i -le 100 ]
  do
    ((sum+=$i))
    ((i++))
  done
echo $sum 

# 方法很多-->這裡以一種炫技的方式進行
           

shell中各種符号的說

說明:shell本身'不适合計算',效率'低'

注意:多使用'成熟的算法',代碼執行'效率'更高
           

④  使用while循環豎向列印10、9、8…

#!/bin/bash
i=10
while [ $i -gt 0 ]
  do
    echo "$i"
    ((--i))
  done

'注意':與之前的做對比!

'補充':vim'腳本'生成
           

NAT相關的

⑤  手機充值10元,每發一次短信花費0.15元,目前餘額小于0.15元不能發短信,提示餘額不足,請充值,可以允許使用者充值後繼續發短信

#!/bin/bash
# 1元是100分
# 餘額的初始化
total=0
# 提示-->選項
menu='
1:充值
2:發送資訊
3:退出
'
# 充值
pay(){
  read -t 10 -p "Pls input pay money:" num
  # 輸入的不是整數
  expr ${num} + 1 &>/dev/null
  [ $? -ne 0 ]&&{
    echo "Input error"
    return 1
  }
  # 輸入的合法的整數
  if [ ${num} -gt 0 ];then
    # 變量都是全局的,可以在其它地方引用!
    total=$(( $total + $num * 100 ))
  else
    echo "Input error"
    return 1
  fi
}
 
# 發短信

send(){
  if [ ${total} -gt 15 ];then    # 是不是餘額小于0.15元
    echo "send messages is ok."
    total=$(( $total - 15 ))
  else
    echo "餘額不足!"
  fi
}
 
while true
do
  echo "目前餘額:${total}"
  echo ${menu}
  read -t 10 -p "Pls input a num:" choice   # 與前面的menu對應
  case ${choice} in
    1) pay        # 沖值後不退出,用while循環!
    ;;
    2) send
    ;;
    3) exit 0     # 結束充值
    ;;
    *)
  esac
done 

# 說明:主要的和i鍛煉shell的邏輯!
           

Shell中小數計算的兩種方式

⑥  while按行讀取檔案的方式

# 方式一

    exec <FILE
    sum=0
    while read line
    do
      cmd
    done

# 方式二

    cat ${FILE_PATH} | while read line
    do
      cmd
    done

# 方式三

    while read line
    do
      cmd
    done<FILE
           

⑦  計算apache一天的日志中所有行的各元素的通路位元組數的總和

#/bin/bash
    exec access.log                       # 讀取日志
    while read line                  
    do
      i=`echo $line|awk '{print $10}'     # 擷取内容`
      expr $i + 1 &>/dev/null             # 判斷是不是整數
      if [ $? -ne 0 ];then
        continue
      fi
      ((sum+=i))
    done
    [ -n "$sum" ] && echo $sum            # 最終存在内容則列印
           

⑧  讀取一個檔案,倒插入一個新的檔案,清空原檔案

#!/bin/bash
file=/root/read.sh
num=`wc -l ${file}|awk -F ' ' '{print $1}'`
while [ ${num} -gt 0 ]
do
  line=`tail -1 ${file}`                       # 檔案倒數一行的内容
  echo ${line}
  echo ${line}>>/root/read_bak.sh
  sed -i '$d' ${file}                          # 把讀入此行的内容删除
  num=`wc -l ${file}|awk -F ' ' '{print $1}'`  # 下一行内容的寫入
done 
           

三    while循環小結

1、while循環的特長是執行'守護程序'以及我們希望循環'不退出'持續執行的場景,用'頻率小于1分鐘'的循環處理,其他的while循環幾乎都可以'被for循環替代'

2、幾乎所有的case語句都可以用if語句替換,一般在系統啟動腳本傳入'少量固定規則'字元串,用case語句,其他普通判斷多用if

3、工作中if和for'最常用',其次while(守護程序)和case(服務啟動腳本)
           

繼續閱讀