1. 程式人生 > >《Shell 程式設計》09_while 迴圈和 until 迴圈

《Shell 程式設計》09_while 迴圈和 until 迴圈

《Shell 程式設計》09_while 迴圈和 until 迴圈

標籤(空格分隔): Shell


文章目錄

9.1 當型和直到型迴圈語法

9.1.1 while 迴圈語句

while 迴圈語句的基本語法為:

while <條件表示式>
do
    cmd...
done

9.1.2 until 迴圈語句

until <條件表示式>
do 
    cmd...
done

9.1.3 範例

例 9-1 每隔 2 秒在螢幕上輸出一次負載值。

#!/bin/bash
while true #<== 表達條件永遠為真,會一直執行,稱之為守護程序。
do
    uptime
    sleep 2
done

將負載值追加到 log 裡,使用微秒單位

#!bin/bash
while [ 1 ]
do
    uptime >>/tmp/uptime.log
    usleep 2000000
done

通過在指令碼的結尾使用 & 符號來在後臺執行指令碼

[[email protected] scripts]# sh 9_1.sh &
[2] 15344
[[email protected] scripts]# tail -f /tmp/uptime.log
 09:49:34 up 1 day,  7:25,  2 users,  load average: 0.00, 0.01, 0.05
 09:49:36 up 1 day,  7:25,  2 users,  load average: 0.00, 0.01, 0.05
 09:49:38 up 1 day,  7:25,  2 users,  load average: 0.00, 0.01, 0.05
 09:49:40 up 1 day,  7:25,  2 users,  load average: 0.00, 0.01, 0.05
 ...

9.2 讓 Shell 指令碼在後臺執行的知識

usage description
sh while1.sh & 把指令碼 while1.sh 放到後臺執行
ctrl+c 停止執行當前指令碼或任務
ctrl+z 暫停執行當前指令碼或任務
bg 把當前指令碼或任務放到後臺執行,background
fg 把當前指令碼或任務放到前臺執行,如果有多個任務,可以使用 fg 加任務編號調出對應的指令碼任務,frontground
jobs 檢視當前執行的指令碼任務
kill 關閉執行的指令碼任務,即以 “ kill %任務編號 ” 的形式關閉指令碼
[[email protected] scripts]# sh 194load.sh &
[1] 16043
[[email protected] scripts]# fg
sh 194load.sh
^Z
[1]+  Stopped                 sh 194load.sh
[[email protected] scripts]# bg
[1]+ sh 194load.sh &
[[email protected] scripts]# jobs
[1]+  Running                 sh 194load.sh &
[[email protected] scripts]# fg 1
sh 194load.sh
^C

使用 kill 命令關閉 jobs 任務指令碼

[[email protected] scripts]# jobs
[1]-  Running                 sh 194load.sh &
[2]+  Running                 sh 194load.sh &
[[email protected] scripts]# kill %2
[[email protected] scripts]# jobs
[1]-  Running                 sh 194load.sh &
[2]+  Terminated              sh 194load.sh

程序管理的Linux 相關命令:

  • kill、killall、pkill:殺掉程序。
  • ps:檢視程序。
  • pstree:顯示程序狀態樹。
  • top:顯示程序。
  • renice:改變優先權。
  • nohup:使用者退出系統之後繼續工作。
  • pgrep:查詢匹配條件的程序。
  • strace:跟蹤一個程序的系統呼叫清理。
  • ltrace:跟蹤程序呼叫庫函式的情況。

例 9-2 使用 while 迴圈或 until 迴圈豎向列印 54321。

#!/bin/bash
i=5
#while ((i>0))
#while [[ $i > 0 ]]
#while [ $i -gt 0 ]
until [[  i < 1 ]]
do
    echo "$i"
    ((i--))
done

例 9-3 猜數字遊戲。首先讓系統隨機生成一個數字,範圍為(1-60),讓使用者輸入所猜的數字。如果不符合要求,則給予或高或低的猜對後則給出猜對所用的次數。

#!/bin/bash
cnt=0
NUM=$((RANDOM%61))
input(){
    read -p "pls input a num:" num
    expr $num + 1 &>/dev/null
    [ $? -ne 0 ] && echo "pls input a 'num'." 
    input
}

guess(){
    ((cnt++))
    if [ $num -eq $NUM ]; then
        echo "You are right."
        if [ $cnt - le 3 ]; then
            echo "You have try $cnt times, excellent!"
        elif [ $cnt -gt 3 -a $cnt le 6 ]; then
            echo "You have try $cnt times, good."
        elif [ $cnt -gt 6 ]; then
            echo "You have try $cnt times."
        fi
        exit 0
    elif [ $num -gt $NUM ]; then
        echo "It is too big. Try again."
        input
    elif [ $num -lt $NUM ]; then
        echo "It is too small. Try again."
        input
    fi    
}

main(){
    input 
    while true
    do
        guess
    done
}

9.3 while 迴圈按行讀檔案的方式總結

方式 1: 採用 exec 讀取檔案,然後進入 while 迴圈處理

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

方式 2:使用 cat 讀取檔案內容,然後通過管道進入 while 迴圈處理

cat FILE_PATH|while read line
do
    cmd
done

方式 3:在 while 迴圈結尾 done 處輸入重定向指定讀取的檔案。

while read line
do
    cmd
done<FILE

小結

1)while 迴圈結構及相關語句綜合實踐小結

  • while 迴圈的特長是執行守護程序,以及實現我們希望迴圈持續執行不退出的應用,適用於頻率小於 1 分鐘的迴圈處理,其他的 while 迴圈幾乎都可以被 for 迴圈及定時任務 crond 功能所替代。
  • case 語句可以用 if 語句來替換,而在系統啟動指令碼時傳入少量固定規則字串的情況下,多用 case 語句,其他普通判斷多用 if 語句。
  • 一句話場景下,if 語句、for 語句最常用,其次是 while(守護程序)、case(服務啟動指令碼)。

2)Shell 指令碼中各個語句的使用場景

  • 條件表示式,用於簡短的條件判斷及輸出(檔案是否存在,字串是否為空等)。
  • if 取值判斷,多用於不同值數量較少的情況。
  • for 最常用於正常的迴圈處理中。
  • while 多用於守護程序、無限迴圈(要加 sleep 和 usleep 控制頻率)場景。
  • case 多用於服務啟動指令碼中,列印選單可用 select 語句,不過很少見,一般用 cat 的 here 文件方法來替代。
  • 函式的作用主要是使編碼邏輯清晰,減少重複語句開發。