Shell編程之循環(huán)語句示例詳解
一、使用 for 循環(huán)語句
1. for 語句的結構
- 使用 for 循環(huán)語句時,需要指定一個變量及可能的取值列表,針對每一個不同的取值重復執(zhí)行相同的命令序列,直到變量值用完退出循環(huán)。
- for 循環(huán)語句的語法結構如下
for 變量名 in 取值列表 do 命令序列 done
上述語句結構中,操作對象為用戶指定名稱的變量,并通過 in 關鍵字為該變量預先設置了一個取值列表,多個取值之間以空格進行分隔。位于 do 和 done 之間的命令序列稱為“循環(huán)體”,其中的執(zhí)行語句需要引用變量以完成相應的任務。
2. for 語句的執(zhí)行流程
- 首先將列表中的第1個取值賦給變量,并執(zhí)行 do···done 循環(huán)體中的命令序列
- 然后將列表中的第2個取值賦給變量,并執(zhí)行循環(huán)體中的命令序列……
- 以此類推,直到列表中的所有取值用完,最后將跳至 done 語句,表示結束循環(huán)
3. for 語句應用示例
根據(jù)姓名列表批量添加用戶,操作如下
[root@localhost /home]#vim /opt/user.txt #用戶列表文件 wangwu zhangsan lisi [root@localhost /home]#vim fo2.sh #批量添加或刪除用戶腳本 #!/bin/bash ULIST=$(cat /opt/user.txt) for UNAME in $ULIST do useradd $UNAME # userdel -r $UNAME &>/dev/null echo "123456" |passwd --stdin $UNAME &>/dev/null echo "創(chuàng)建用戶成功" # echo "刪除用戶中...";sleep 2 # echo "刪除成功" done wq保存并退出 #如果想要批量刪除用戶就可以把上面注釋去掉,并把創(chuàng)建用戶的命令給注釋掉 [root@localhost /home]#. fo2.sh #測試并確認執(zhí)行的結果 創(chuàng)建用戶成功 創(chuàng)建用戶成功 創(chuàng)建用戶成功 [root@localhost /home]#tail -3 /etc/passwd wangwu:x:1001:1001::/home/wangwu:/bin/bash zhangsan:x:1002:1002::/home/zhangsan:/bin/bash lisi:x:1003:1003::/home/lisi:/bin/bash
根據(jù) IP 地址列表檢查主機狀態(tài)
[root@localhost /home]#vim /opt/ipadds.txt #IP地址列表文件 192.168.8.1 192.168.8.2 192.168.8.3 [root@localhost /home]#vim fo3.sh #循環(huán)檢查各主機的腳本 #!/bin/bash HLIST=$(cat /opt/ipadds.txt) for IP in $HLIST do ping -c 3 -i 0.2 -W 3 $IP &>/dev/null #-c是發(fā)送ping包的數(shù)量為3 if [ $? -eq 0 ] #-i是收發(fā)信息的間隔時間為0.2s then #-W是超時時間為3s echo "HOST $IP is up" else echo "HOST $IP is down" fi done [root@localhost /home]#sh fo3.sh #使用sh命令就不用賦予權限才能運行 HOST 192.168.8.1 is up HOST 192.168.8.2 is up HOST 192.168.8.3 is down
密碼輸入正確和錯誤提示
[root@localhost /home]#vim fo4.sh #!/bin/bash init=123456 for i in {1..3} do read -p "請輸入用戶密碼:" passwd if [ $passwd == $init ] then echo "密碼正確" exit fi done echo "密碼錯誤" [root@localhost /home]#sh fo4.sh 請輸入用戶密碼:1 請輸入用戶密碼:1 請輸入用戶密碼:1 密碼錯誤 #密碼輸入錯誤三次直接退出交互界面 [root@localhost /home]#sh fo4.sh 請輸入用戶密碼:123456 密碼正確 #密碼輸入成功提示密碼輸入正確
二、while 循環(huán)語句
for 循環(huán)語句非常適合于列表對象無規(guī)律,且列表來源已固定(如某個列表文件)的場合。而對于要求控制循環(huán)次數(shù)、操作對象按數(shù)字順序編號、按特定條件執(zhí)行重復操作等情況,則更適合使用 while 語句。
1.while 語句的結構
使用 while 循環(huán)語句時,可以根據(jù)特定的條件反復執(zhí)行一個命令序列,直到該條件不再滿足時為止。但是在腳本應用中,應該避免出現(xiàn)死循環(huán)的情況,否則后邊的命令操作將無法執(zhí)行。 循環(huán)體內(nèi)的命令序列中應包括修改測試條件的語句,以便在適當?shù)臅r候使測試條件不再成立,從而結束循環(huán)。 while循環(huán)語句的語法結構如下所示:
2.while 語句的執(zhí)行流程
首先判斷 while 后的條件測試操作結果,如果條件成立,則執(zhí)行 do···done 循環(huán)體中的命令序列返回 while 后再次判斷條件測試結果,如果條件仍然成立,則繼續(xù)執(zhí)行循環(huán)體再次返回到 while 后,判斷條件測試結果…如此循環(huán)直到 while 后的條件測試結果不再成立為止,最后跳轉到 done 語句,表示結束循環(huán)
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-kanpyiRh-1644830523881)(C:\Users\xiaozhu\AppData\Roaming\Typora\typora-user-images\1644829317814.png)]
3. while 語句應用示例
① 批量添加規(guī)律編號的用戶
[root@localhost /home]#vim useradd.sh #批量添加用戶腳本 #!/bin/bash PREFIX="gl" i=1 while [ $i -le 20 ] do useradd ${PREFIX}$i echo "123456"|passwd --stdin ${PREFIX}$i &>/dev/null let i++ done [root@localhost /home]#sh useradd.sh [root@localhost /home]#grep "gl" /etc/passwd |tail -3 gl18:x:1021:1021::/home/gl18:/bin/bash gl19:x:1022:1022::/home/gl19:/bin/bash gl20:x:1023:1023::/home/gl20:/bin/bash
上述腳本代碼中,使用變量 i 來控制用戶名稱的編號,初始賦值為1,并且當取值大于20時終止循環(huán)。在循環(huán)中,通過語句 “let i++”(等同于i=‘expr $i+1’)來使變量i的值增加1,因此當執(zhí)行第一次循環(huán)后i的值將變成2,執(zhí)行第2次循環(huán)后i的值將變成3…以此類推。
如果想要刪除添加的用戶,只需要把 while循環(huán)中添加用戶的命令序列改為刪除用戶的操作即可,操作如下:
[root@localhost /home]#vim useradd.sh #!/bin/bash PREFIX="gl" i=1 while [ $i -le 20 ] do userdel -r ${PREFIX}$i # echo "123456"|passwd --stdin ${PREFIX}$i &>/dev/null let i++ done [root@localhost /home]#sh useradd.sh [root@localhost /home]#id gl20 #確認用戶是否刪除成功 id: gl20: no such user
② 猜數(shù)字大小
[root@localhost /home]#vim w4.sh #!/bin/bash NUM=8 while true do read -p "請輸入數(shù)字:" sz if [ $sz -eq $NUM ];then echo "你猜對了!" break elif [ $sz -gt $NUM ];then echo "你猜大了" elif [ $sz -lt $NUM ];then echo "你猜小了" fi done [root@localhost /home]#sh w4.sh 請輸入數(shù)字:2 你猜小了 請輸入數(shù)字:4 你猜小了 請輸入數(shù)字:6 你猜小了 請輸入數(shù)字:8 你猜對了!
③ 猜價格游戲
[root@localhost /home]#vim w5.sh #!/bin/bash PRICE=$(expr $RANDOM % 1000) a=0 echo "商品實際價格范圍為0~999,猜猜價格多少?" while true do read -p "請輸入你猜測的價格:" INT let a++ if [ $INT -eq $PRICE ];then echo "恭喜你猜對了,實際價格是$PRICE" echo "你總共猜了 $a次" break elif [ $INT -gt $PRICE ];then echo "你猜高了" else echo "你猜低了" fi done [root@localhost /home]#sh w5.sh 商品實際價格范圍為0~999,猜猜價格多少? 請輸入你猜測的價格:188 你猜低了 請輸入你猜測的價格:288 你猜低了 ...... 省略 你猜高了 請輸入你猜測的價格:920 恭喜你猜對了,實際價格是920 你總共猜了 12次
三、Shell 函數(shù)
1.概述
在編寫shelI腳本時,你經(jīng)常會發(fā)現(xiàn)在多個地方使用了同一段代碼。如果只是一小段代碼,一般也無關緊要。但是在shell腳本中多次重寫大塊代碼段就太累人了。為了解決這個問題,我們可以將 shell 腳本代碼放進函數(shù)中封裝起來,這樣就能在腳本中的任何地方多次重復使用它了。
2.函數(shù)的基本格式
[function] 函數(shù)名(){ 命令序列 [return x] #return x 的作用是命令序列執(zhí)行完后返回給系統(tǒng)一個值,可省略 } 或者 #也可以省略掉[function],它表示該函數(shù)的功能 函數(shù)名() { #函數(shù)名后面()是沒有內(nèi)容的 命令序列 #我們執(zhí)行的命令內(nèi)容放在{}里面 }
- 函數(shù)一結束就取返回值,退出的狀態(tài)碼必須是0~255
- 由于退出狀態(tài)碼必須小于256,函數(shù)的結果必須生成一個小于256的整數(shù)值,任何大于256的值都會產(chǎn)生一個錯誤值。
3. 函數(shù)應用示例
定義一個輸入兩個數(shù)求和的腳本
[root@localhost /home]#vim summ.sh #!/bin/bash sum(){ read -p "請輸入第一個數(shù):" NUM1 read -p "請輸入第二個數(shù):" NUM2 echo "你輸入的二個數(shù)為:$NUM1 和 $NUM2." SUM=$[$NUM1 + $NUM2] echo "兩個數(shù)和為:$SUM" } sum [root@localhost /home]#sh summ.sh 請輸入第一個數(shù):8 請輸入第二個數(shù):9 你輸入的二個數(shù)為:8 和 9. 兩個數(shù)和為:17
返回值的范圍
[root@localhost /home]#vim retun.sh #!/bin/bash function test1 { read -p "請輸入數(shù)字:" num return $[num*2] } test1 echo $? [root@localhost /home]#sh retun.sh 請輸入數(shù)字:3 6 [root@localhost /home]#sh retun.sh 請輸入數(shù)字:127 254 [root@localhost /home]#sh retun.sh 請輸入數(shù)字:128 0
函數(shù)的階乘
[root@localhost /home]#vim cc.sh #!/bin/bash fa () { if [ $1 -eq 1 ] then echo 1 else local tp=$[ $1 - 1 ] local res=$(fa $tp) echo $[ $1 * $res ] fi } read -p "請輸入:" num res=$(fa $num) echo $res [root@localhost /home]#sh cc.sh #5*4*3*2*1=120 請輸入:5 120 [root@localhost /home]#sh cc.sh #3*2*1=6 請輸入:3 6
四、數(shù)組
1. 定義數(shù)組
可以在單行中使用數(shù)值列表來定義一個數(shù)組
array_var=(test1 test2 test3 test4) #這些值將會存儲在以0為起始索引的連續(xù)位置上 或者 #將數(shù)組定義為一組“索引—值” array_var=[0]="test1" array_var=[1]="test2" array_var=[2]="test3" array_var=[3]="test4" array_var=[4]="test5" array_var=[5]="test6"
精確的給每一個下標索引定義一個值加入數(shù)組,索引數(shù)字可以不連續(xù)
num=([0]=55 [1]=66 [2]=77 [4]=88) 數(shù)組名=([0]=value [1]=value [2]=value. . .)
先把要加入數(shù)組的元素全部先賦值給一個變量,然后引用這個變量加入到數(shù)組
list=“11 12 13 14”
num=($list)
2. 獲取數(shù)組長度
打印出特定索引的數(shù)組元素內(nèi)容
#echo ${array_var [0]} test1 index=5 #echo ${array_var[$index]} test6
以列表形式打印出數(shù)組中的所有值
#echo ${array_var[*]} test1 test2 test3 test4 test5 test6 或者 #echo ${array_var[@]} test1 test2 test3 test4 test5 test6
打印數(shù)組長度(即數(shù)組中元素的個數(shù))
#echo ${#array_var[*]}6
數(shù)組元素的遍歷
[root@localhost ~]#arr=(1 2 3 4 5 6) [root@localhost ~]#for i in ${arr[*]} > do > echo $i > done 1 2 3 4 5 6
3.元素切片
[root@localhost ~]#arr=(1 2 3 4 5 6 7 8 9) [root@localhost ~]#echo ${arr[*]} 1 2 3 4 5 6 7 8 9 [root@localhost ~]#echo ${arr[*]:2:3} #提取出第二個數(shù)后面的三個值 3 4 5 [root@localhost ~]#echo ${arr[*]:2:5} 3 4 5 6 7 [root@localhost ~]#echo ${arr[*]:2:2} 3 4 [root@localhost ~]#echo ${arr[*]:0:6} 1 2 3 4 5 6
4.元素替換
[root@localhost ~]#arr=(1 2 3 4 5 6 7 8 9) [root@localhost ~]#echo ${arr[*]} 1 2 3 4 5 6 7 8 9 [root@localhost ~]#echo ${arr[*]/3/88} #3指的是查找數(shù)主里面的字符,88指的是需要替換的字符 1 2 88 4 5 6 7 8 9 [root@localhost ~]#echo ${arr[*]/5/66} 1 2 3 4 66 6 7 8 9
5.元素刪除
[root@localhost ~]#arrt=(1 2 33 4 566 6) [root@localhost ~]#echo ${arrt[*]} 1 2 33 4 566 6 [root@localhost ~]#unset arrt[2] #刪除的時候是以下標的形式來進行刪除,下標2對應的字符為33 [root@localhost ~]#echo ${arrt[*]} 1 2 4 566 6 [root@localhost ~]#unset arrt[4] #下標4對應的字符為566 [root@localhost ~]#echo ${arrt[*]} 1 2 4 6
6.冒泡排序
概念: 指的是它會遍歷若干次要排序的數(shù)列,每次遍歷時,它都會從前往后依次的比較相鄰兩個數(shù)的大?。蝗绻罢弑群笳叽?,則交換它們的位置。這樣,一次遍歷之后,最大的元素就在數(shù)列的末尾! 采用相同的方法再次遍歷時,第二大的元素就被排列在最大元素之前。重復此操作,直到整個數(shù)列都有序為止。 案例
[root@localhost /home]#vim mp.sh #!/bin/bash array=(20 40 30 10 60 50) echo "old_array:${array[*]}" lt=${#array[*]} #定義比較輪數(shù),比較輪數(shù)為數(shù)組長度減1,從1開始; for ((i=1;i<$lt;i++)) do #確定比較元素的位置,比較相鄰的兩個元素,較大的數(shù)往后放,小的數(shù)往前放,并且每 輪比較次數(shù)需要隨著輪數(shù)遞減 for ((j=0;j<$lt-i;j++)) do #定義第一個元素的值 first=${array[$j]} #定義第二個元素的值 k=$[$j+1] second=${array[$k]} #如果第一個元素比第二個元素大,就進行互換 if [ $first -gt $second ] then #把第一個元素值存放到臨時變量中 tmp=$first #把第二個元素值賦給第一個元素 array[$j]=$second #把臨時變量(第一個元素原值)賦給第二個元素 array[$k]=$tmp fi done done echo "new_array:${array[*]}"
五、Shell 腳本調(diào)試
在Shell 腳本開發(fā)中,經(jīng)常碰到一些規(guī)范方面的問題,例如忘了便用引號或在 if 語句末尾處忘記加 fi 結束。 要注意把復雜的腳本簡單化,要思路清晰,并且分段實現(xiàn)。當執(zhí)行腳本時出現(xiàn)腳本錯誤后,不要只看那些提示的錯誤行,而是要觀察整個相關的代碼段。 為避免編寫的腳本出錯,除了在編寫腳本時注意書寫規(guī)范,排除語法錯誤,更重要的是利用調(diào)試腳本工具來調(diào)試腳本。
1.echo 命令
echo命令是最有用的調(diào)試腳本工具之一,一般在可能出現(xiàn)問題的腳本中加入 echo 命令,采用的是分段排查的方式。
2.bash 命令
除了echo 命令之外,bash Shell 也有相應參數(shù)可以調(diào)試腳本。
使用 bash 命令參數(shù)調(diào)試,命令的語法如下:
sh [-nvx] 腳本名
常用的參數(shù)如下所示
① -n:不會執(zhí)行該腳本,僅查詢腳本語法是否有問題,如果沒有語法問題就不顯示任何內(nèi)容,如果有問題會提示報錯。
② -V:在執(zhí)行腳本時,先將腳本的內(nèi)容輸出到屏幕上然后執(zhí)行腳本,如果有錯誤,也會給出錯誤提示。
③ -x:將執(zhí)行的腳本內(nèi)容輸出到屏幕上,這是個對調(diào)試很有用的參數(shù)。
3.set 命令
當腳本較長時,可以使用 set 命令指定調(diào)試一段腳本
常用參數(shù)如下:
set -x #開啟調(diào)試模式 set +x #關閉調(diào)試模式
示例
[root@localhost /home]#cat 1.sh #!/bin/bash set -x for ((i=1;i<=5;i++)) do echo $i done #開啟調(diào)試模式以后會看到每段的反饋結果 [root@localhost /home]#sh 1.sh + (( i=1 )) + (( i<=5 )) + echo 1 1 + (( i++ )) + (( i<=5 )) + echo 2 2 + (( i++ )) + (( i<=5 )) + echo 3 3 + (( i++ )) + (( i<=5 )) + echo 4 4 + (( i++ )) + (( i<=5 )) + echo 5 5 + (( i++ )) + (( i<=5 ))
總結
提示。
③ -x:將執(zhí)行的腳本內(nèi)容輸出到屏幕上,這是個對調(diào)試很有用的參數(shù)。
3.set 命令
當腳本較長時,可以使用 set 命令指定調(diào)試一段腳本
常用參數(shù)如下:
set -x #開啟調(diào)試模式 set +x #關閉調(diào)試模式
示例
[root@localhost /home]#cat 1.sh #!/bin/bash set -x for ((i=1;i<=5;i++)) do echo $i done #開啟調(diào)試模式以后會看到每段的反饋結果 [root@localhost /home]#sh 1.sh + (( i=1 )) + (( i<=5 )) + echo 1 1 + (( i++ )) + (( i<=5 )) + echo 2 2 + (( i++ )) + (( i<=5 )) + echo 3 3 + (( i++ )) + (( i<=5 )) + echo 4 4 + (( i++ )) + (( i<=5 )) + echo 5 5 + (( i++ )) + (( i<=5 ))
總結
Shell 腳本是千變?nèi)f化的,正所謂條條大路通羅馬,shell 腳本中也是如此。一個腳本可以有無數(shù)種寫法,但是思路都是相通的,只要有了思路腳本就自然會寫的很順暢!
到此這篇關于Shell編程之循環(huán)語句的文章就介紹到這了,更多相關Shell循環(huán)語句內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Shell(())實現(xiàn)對整數(shù)進行數(shù)學運算
這篇文章主要介紹了Shell(())實現(xiàn)對整數(shù)進行數(shù)學運算,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-03-03win下調(diào)用putty執(zhí)行命令腳本分享
這篇文章主要介紹了win下調(diào)用putty執(zhí)行命令腳本,可以利用這個實現(xiàn)一些自動化的工作,需要的朋友可以參考下2014-03-03