雲端計算運維一定要掌握的方便省事的Shell迴圈結構(while、for、until詳細範例)

2020-09-29 17:00:57

什麼是shell

Shell是一個命令列直譯器,它為使用者提供了一個向Linux核心傳送請求以便執行程式的介面系統級程式,使用者可以用Shell來啟動、掛起、停止甚至時編寫一些程式。Shell還是一個功能相當強大的程式語言,易編寫,易偵錯,靈活性較強。Shell是解釋執行的指令碼語言,在Shell中可以直接呼叫Linux系統命令

一:shell迴圈語句

1.1:for迴圈

for迴圈的運作方式,是講序列的元素意義取出,依序放入指定的變數中,然後重複執行含括的命令區域(在do和done 之間),直到所有元素取盡為止。
其中,序列是一些字串的組合,彼此用$IFS所定義的分隔符(如空格符)隔開,這些字串稱為欄位。
在這裡插入圖片描述

for      #條件
do   
       #執行命令
done     #結束             

行1,講序列中的欄位迭代放入變數中
行2-4,接著將重複執行do和done之間的命令區域,直到序列中每一個欄位軍處理過為止。

#!/bin/bash
for ((a=10;a>0;a--))
do
  echo -n " TIME $a"
  echo -ne "\r "    #不換行覆蓋輸出
  sleep 1
done

在這裡插入圖片描述

1.2:echo用法

echo [-ne][字串]或 echo [--help][--version]
  補充說明:echo會將輸入的字串送往標準輸出。輸出的字串間以空白字元隔開, 並在最後加上換行號。
  參   數:  -n 不要在最後自動換行
          -e 若字串中出現以下字元,則特別加以處理,而不會將它當成一般
          文字輸出:
          \a 發出警告聲;
          \b 刪除前一個字元;
          \c 最後不加上換行符號;
          \f 換行但遊標仍舊停留在原來的位置;
          \n 換行且遊標移至行首;
          \r 遊標移至行首,但不換行;
          \t 插入tab;
          \v 與\f相同;
          \\ 插入\字元;
          \nnn 插入nnn(八進位制)所代表的ASCII字元;
        --help 顯示幫助
        --version 顯示版本資訊 
  範例 :   [root@localhost ~]# echo "what is your name "

1.3:姓名列表批次建立賬戶

[root@server1 ~]# vi 1.txt 
tom
jerry
wendy
[root@server1 ~]# vim 1.sh
#!/bin/bash
a=$(cat /root/1.txt)
for b in $a
do
 useradd $b
 echo "654321" | passwd --stdin $b
 echo "建立{$b}完成"
done
[root@server1 ~]# sh 1.sh
更改使用者 tom 的密碼 。
passwd:所有的身份驗證令牌已經成功更新。
建立{tom}完成
更改使用者 jerry 的密碼 。
passwd:所有的身份驗證令牌已經成功更新。
建立{jerry}完成
更改使用者 wendy 的密碼 。
passwd:所有的身份驗證令牌已經成功更新。
建立{wendy}完成

語法2:

for ((初始化;;迴圈控制條件;變數變化)do
程式
done

需要注意以下幾點:

  • 初始值:在迴圈開始時,需要給某個變數賦予初始值,如 i=1。

  • 迴圈控制條件:用於指定變數迴圈的次數,i<=100,則只要 i 的值小於等於 100,迴圈就會繼續。

  • 變數變化:每次迴圈之後,變數該如何變化,如 i=i+1,代表每次迴圈之後,變數的值都加 1。

  • 語法二和其他語言中的 for 迴圈類似,也就是事先決定迴圈次數的固定迴圈。先舉一個簡單的例子。
    +、-、*、/

  • (++) 自身變數+1

  • (- -)自身變數-1

  • (+=5) 自身變數

  • (-=)5 自身變數-5

  • ( * )5自身變數*5

lt 可以單獨使用 % 自身變數 %5
+=5 自身變數 +5自身變數 %5
-=5 自身變數-5 * 5自身變數*5
/= 自身變數/5

##continue和break區別)# 1.14:100以內不能整除3的數

[root@server1 ~]# vim c.sh
#!/bin/bash
i=100
while [ $i -gt 0 ]
do
  if [ `expr $i % 3` -eq 0 ];then
    let i--
    continue
else
    echo -n " $i"
fi
let i--
done
[root@server1 ~]# sh c.sh 
 100 98 97 95 94 92 91 89 88 86 ……

shell中let命令

let 對整數進行數學運算
let和雙小括號 (( )) 一樣,let 命令也只能進行整數運算,不能對小數(浮點數)或者字串進行運算。

語法格式
let 表示式
或
let "表示式"
或
let '表示式'
以上方式都等價於 ((表示式))
  • 當表示式中含有 Shell 特殊字元(例如 |)時,需要用雙引號" "或者單引號’ '將表示式包圍起來。
  • 和 (( )) 類似,let 命令也支援一次性計算多個表示式,並且以最後一個表示式的值作為整個 let 命令的執行結果。

二:while迴圈語句

while 迴圈主要用於無限次的迴圈情況,例如登入認證,你不知道多少次可以登入成功,當然可以認為限制登入次數。

在這裡插入圖片描述

1.21:使用while迴圈1-10數位

#!/bin/bash
i=0
while [ $i -le 10 ]
do
echo $i
let i++
done
[root@server1 ~]# sh d.sh 
0
1
2
3
4
5
6
7
8
9
10

1.22:whlie死迴圈

while true:死迴圈有時候也有奇效,可與使用者互動

#!/bin/bash
while true
do
 read -p '輸入tom才可退出:' a
 if [ $a = tom ]
   then
    break
fi
done
echo '退出' 
[root@server1 ~]# sh f.sh 
輸入tom才可退出:a
輸入tom才可退出:tom
退出
[root@server1 ~]# 

1.23:使用whlie批次新增使用者

使用者名稱稱以shuai開頭,按照順序進行排序
一共新增了5個賬戶,即hua1…hua5

#!/bin/bash
a=0
while [ $a -le 5 ]
do
  let a++
  useradd tom$a
  echo "123123" | passwd --stdin tom$a &> /dev/null
  echo "tom$新增完畢"
done
echo "結束"
[root@server1 ~]# sh g.sh 
tom$新增完畢
tom$新增完畢
tom$新增完畢
tom$新增完畢
tom$新增完畢
tom$新增完畢
結束

1.24:10以內所有自然數的平方值 如1*1

#!/bin/bash
num=1
while [ $num -lt 10 ]
do
  a=$(expr $num \* $num)
  echo $a
  let num++
done
[root@server1 ~]# sh 2.sh 
1
4
9
16
25
36
49
64
81

猜商品價格遊戲
通過變數RANDOM獲得亂數
提示使用者猜測並記錄次數,猜中後退出迴圈

#!/bin/bash
#猜商品價格
RR=$(expr $RANDOM % 1000)   #$RANDOM 生成1000以內的亂數
i=0
echo "猜價格遊戲"
while true
 do
 read -p "請輸入商品價格(0-999):" num
 let i++
 if [ $num -eq $RR ];then
 echo "恭喜猜中了"
 echo "恭喜猜中了$i"
 break
elif [ $num -gt $RR ];then
 echo "猜高了"
else
 echo "猜低了"
fi
done
[root@server1 ~]# sh 3.sh 
猜價格遊戲
請輸入商品價格(0-999):500
猜高了
請輸入商品價格(0-999):255
猜低了
請輸入商品價格(0-999):400
猜高了
請輸入商品價格(0-999):350
猜高了
請輸入商品價格(0-999):300
猜高了
請輸入商品價格(0-999):275
猜低了
請輸入商品價格(0-999):285
猜低了
請輸入商品價格(0-999):293
猜低了
請輸入商品價格(0-999):296
猜低了
請輸入商品價格(0-999):299
恭喜猜中了
一共猜了了10次

三:continue和break區別

break 命令可以帶一個引數,一個不帶引數的break 迴圈只能退出最內層的迴圈,而break N可以退出N 層迴圈
continue 命令也可以帶一個引數,一個不帶引數的continue 命令只去掉本次迴圈的剩餘程式碼,而continue N 將會把N 層迴圈剩餘的程式碼都去掉,但是迴圈的次數不變

#!/bin/sh  
for i in a b c d
do
     echo
        echo -n "$i "
        for j in `seq 10`
        do
                if [ $j == 5 ]; then
                #       break
                #       break 2
                #       continue
           continue 2
            fi
        echo -n "$j "
        done
        echo
done
echo
break結果:
a 1 2 3 4 
b 1 2 3 4 
c 1 2 3 4 
d 1 2 3 4 
break 2的結果:
a 1 2 3 4 
continue結果:
a 1 2 3 4 6 7 8 9 10 
b 1 2 3 4 6 7 8 9 10 
c 1 2 3 4 6 7 8 9 10 
d 1 2 3 4 6 7 8 9 10
continue 2的結果:
a 1 2 3 4 
b 1 2 3 4 
c 1 2 3 4 
d 1 2 3 4 
# 四:untli迴圈語句
!

四:until迴圈語句

在這裡插入圖片描述

重複測試某個條件,只要條件不成立則反覆執行

until 條件測試操作
do
 命令序列
done
while 未超過20
do
 數位依次增加
done:

行1,如果條件測試結果為假(傳回值不為0),就進入迴圈。
行3,執行命令區域。這些命令中,應該有改變條件測試的命令,這樣子,才有機會在有限步驟後結束執行until 迴圈(除非你想要執行無窮迴圈)。
行4,回到行1,執行until命令

1.41:計算1-20的和

通過迴圈累計的方式計算1-20的和
until跟whlie相反是命令不成立就會進入迴圈=whlie前面加!

#!/bin/bash
k=1
s=0
until [ $k -eq 11 ]     #當取值為21就會成立就不會進入迴圈'
do
 let s+=$k
 let k++
done
echo "和:$s"
[root@server1 ~]# sh b.sh 
和:55

1.42:until語句應用

為指定使用者傳送線上訊息

  • 若指定使用者不線上(未登陸系統),則每10分鐘(實驗中為了測試效果,可改為5s)試一次,直至使用者登入系統後再傳送資訊
  • 使用者名稱與訊息通過為止引數傳遞給指令碼
#!/bin/bash
username=$1
#判斷格式引數是否為空
if [ $# -lt 1 ]
 then
 echo "Usage:`basename $0` <username> [<message>]"
 exit 1
fi
#判斷賬號是否存在
if grep "^$username:" /etc/passwd &> /dev/nell;then :
  else
        echo "使用者不存在"
        exit 2
fi
#判斷使用者是否線上
until who | grep "$username" &> /dev/null
do
        echo "使用者不線上,正在嘗試連線"
        sleep 5
done
------------------------------------------------


`basename $0`值顯示當前指令碼或命令的名字
Message:定義傳送內容
oot@localhost opt]# bash test.sh 
Usage:test.sh <username> [<message>]
#測試不存在使用者
[root@localhost opt]# sh test.sh sushan
使用者不存在
#使用者不線上時
[root@localhost opt]# ./mes.sh sushan
使用者不線上,正在嘗試連線
使用者不線上,正在嘗試連線
使用者不線上,正在嘗試連線

準備了好多天肝了出來
如果覺得對您有用的話,點個贊再走吧!!!