8月25日 腳本進(jìn)階2

1、while循環(huán)

?while CONDITION; do
循環(huán)體
done
?CONDITION:循環(huán)控制條件;進(jìn)入循環(huán)之前,先做一次判斷;每一次循環(huán)之后會(huì)再次做判斷;條件為“true”,則執(zhí)行一次循環(huán);直到條件測(cè)試狀態(tài)為“false”終止循環(huán)
?因此:CONDTION一般應(yīng)該有循環(huán)控制變量;而此變量的值會(huì)在循環(huán)體不斷地被修正
?進(jìn)入條件:CONDITION為true
?退出條件:CONDITION為false
舉例

#!/bin/bash
sum=0
i=1
while [ $i -le 100 ];do  ---先進(jìn)行判斷,如果為真,則執(zhí)行循環(huán)體
    let sum+=i   ---表示sum=sum+i
    let i++      ---表示i=i+1
done
      echo sum is $sum
[root@redhat7 app]#i=0;let i++;echo $?   ---i++表示先賦值再相加,此時(shí)i=0,規(guī)定如果let后的值是零,則退出狀態(tài)碼為1
1
[root@redhat7 app]#i=0;let ++i;echo $?---表示先相加再賦值,此時(shí)let后的值是1
0

總結(jié):要引起注意,兩個(gè)返回的值不一樣,不小心可能會(huì)出錯(cuò),因?yàn)閣hile進(jìn)行判斷時(shí)真就進(jìn)行循環(huán),假就退出循環(huán)。

#!/bin/bash
read -p "please input nework(eg:192.168.0.0): " network
      netid=`echo $network|cut -d. -f1-3` ---取出網(wǎng)絡(luò)id位并定義為變量
      hostid=1
      up=0
      down=0
      while [ $hostid -le 254 ];do
     if  ping -c1 -w1 $netid.$hostid &>/dev/null;then ---pingIP地址
         echo "the $netid.$hostid is up"  ---如果成功則打印ip地址是up
                 let up++   ---并且讓up增加一個(gè)
     else
         echo "the $netid.$hostid is down"
                   let down++
    fi
                        let hostid++

    done
            echo up host is $up
            echo down host is $down

如何實(shí)現(xiàn)死循環(huán)

[root@redhat7 app]#while true;do echo xxx;sleep 1;done  ---while 后
面的條件如果一直是真,則不會(huì)退出循環(huán)體,就會(huì)一直循環(huán),實(shí)現(xiàn)死
循環(huán)。
xxx
xxx
[root@redhat7 app]#true   ---true的值返回的總是真,可以實(shí)現(xiàn)死循環(huán)
[root@redhat7 app]#echo $?
0

實(shí)現(xiàn)每5秒鐘監(jiān)控一下http這個(gè)服務(wù)是否正常運(yùn)行,如果不正常運(yùn)行,就重啟服務(wù),并寫(xiě)進(jìn)日志

#!/bin/bash
while true;do  ---實(shí)現(xiàn)死循環(huán)
  if killall -0 httpd &>/dev/null;then   ---監(jiān)控httpd服務(wù)是否正常運(yùn)行,發(fā)0信號(hào)就可以監(jiān)控
         echo the htttpd service is normal
 else
        systemctl restart httpd&>/dev/null
        echo "`date '+%F %T'` restart httpd " >>/app/httpd.log  ---將什
么時(shí)間重啟的服務(wù)寫(xiě)進(jìn)日志
 fi
     sleep 5  ---睡眠5秒后繼續(xù)執(zhí)行循環(huán)體
done

用while循環(huán)實(shí)現(xiàn)國(guó)際象棋

#!/bin/bash
i=1
 while [ $i -le 8 ];do
    j=1
   while [ $j -le 8 ];do
    let flag=i+j
   if [ $[flag%2] -eq 0 ];then  ---表示進(jìn)行算術(shù)運(yùn)行,還可以寫(xiě)成
$(flag%2)= $[flag%2],表示取余數(shù)的意思,能被2整除就是偶數(shù)。
        echo -ne "\033[41m  \033[0m"
   else
        echo -ne "\e[43m  \e[0m"
   fi
          let j++
   done
      echo 
        let i++
 done
Paste_Image.png

總結(jié):國(guó)際象棋的特點(diǎn)是八行八列,最外面的while循環(huán)打印八行,里面的whlie循環(huán)打印八列,其中行號(hào)加列號(hào)為偶數(shù)的是一種背景色,是奇數(shù)的為另外一種背景色,根據(jù)這個(gè)特點(diǎn)可以規(guī)定什么時(shí)候打印什么背景色。

2、until循環(huán)

?until CONDITION; do
循環(huán)體
?done
?進(jìn)入條件:CONDITION 為false
?退出條件:CONDITION 為true
總結(jié):until循環(huán)和while循環(huán)的格式相同,但判斷時(shí)是假才進(jìn)入循環(huán)體,和while循環(huán)正好相反。

3、循環(huán)控制語(yǔ)句continue

?用于循環(huán)體中
?continue [N]:提前結(jié)束第N層的本輪循環(huán),而直接進(jìn)入下一輪判斷;最內(nèi)層為第1層

#!/bin/bash
i=1
 while [ $i -le 10 ];do
     [ $i -eq 5 ]&&continue  ---結(jié)束本輪循環(huán),而不是退出整個(gè)循環(huán)
     echo i=$i
     let i++
done
[root@redhat7 app]#./continue.sh --執(zhí)行到5的時(shí)候,就結(jié)束本輪循
環(huán),i也不會(huì)加1,此時(shí)1一直都是5,頁(yè)不會(huì)打印,因?yàn)榇蛴∈窃?continue后面,就會(huì)一直停著,也不會(huì)退出。
i=1
i=2
i=3
i=4
#!/bin/bash
i=0
 while [ $i -le 10 ];do
     let i++
   if  [ $i -eq 5 ];then
       continue
   else
     echo i=$i
   fi
done
執(zhí)行結(jié)果
[root@redhat7 app]#./continue.sh ---當(dāng)遇到5時(shí)就結(jié)束本輪循環(huán),不
進(jìn)行打印5
i=1
i=2
i=3
i=4
i=6
i=7
i=8
i=9
i=10
i=11

4、循環(huán)控制語(yǔ)句break

?用于循環(huán)體中
?break [N]:提前結(jié)束第N層循環(huán),最內(nèi)層為第1層

#!/bin/bash
i=0
 while [ $i -le 10 ];do
     let i++
   if  [ $i -eq 5 ];then
       break
   else
     echo i=$i
   fi
done
執(zhí)行情況
[root@redhat7 app]#./break.sh 
i=1
i=2
i=3
i=4

continue和break的區(qū)別:后面不加數(shù)字的時(shí)候默認(rèn)都是第1層,也就是最內(nèi)層,continue是結(jié)束第1層的本輪循環(huán),而break是結(jié)束第1層循環(huán),比如第一層有10個(gè)循環(huán),continue只是結(jié)束本層的第幾個(gè)循環(huán),而break是跳出本層的整個(gè)循環(huán)。

for i in {1..10};do
  for j in {1..10};do
      echo -n "$j "
  [ $j -eq 5 ]&&continue 2  ---表示當(dāng)j=5時(shí)就跳出第2層也就是最外面層的某一次循環(huán),進(jìn)行下一次循環(huán),所以不會(huì)執(zhí)行echo換行。
  done
      echo 
  done
[root@redhat7 app]#./continue.sh 
1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5
2 3 4 5 1 2 3 4 5 [root@redhat7 app]#vim continue.sh 
#!/bin/bash
for i in {1..10};do
  for j in {1..10};do
      echo -n "$j "
  [ $j -eq 5 ]&&break 2  ---表示當(dāng)j=2時(shí)跳出整個(gè)最外層的循環(huán)
     done
      echo 
done
[root@redhat7 app]#./continue.sh 
1 2 3 4 5

5、循環(huán)控制shift命令

?shift [n]
?用于將參量列表list 左移指定次數(shù),缺省為左移一次。
?參量列表list 一旦被移動(dòng),最左端的那個(gè)參數(shù)就從列表中刪除。while 循環(huán)遍歷位置參量列表時(shí),常用到shift

舉例

#!/bin/bash
while [ $# -gt 0 ];do
    echo $*
   shift
    done
[root@redhat7 app]#./shift.sh a b c d e f 
a b c d e f
b c d e f
c d e f
d e f
e f
f
#!/bin/bash
while [ $# -gt 0 ];do
     id $1 &>/dev/null && continue
     useradd $1 &>/dev/null && echo $1 is created
   shift   ---如果不加shift,始終都是第一個(gè)參數(shù),就創(chuàng)建不了其他的
用戶了
done
[root@redhat7 app]#./shiftuser.sh lixinru fanbingbing lixiaolu
lixinru is created
fanbingbing is created
lixiaolu is created

6、特殊用法

  • while和read配合使用可以依次處理文件或命令的每一行

?while循環(huán)的特殊用法(遍歷文件的每一行):
while read line; do
循環(huán)體
done < /PATH/FROM/SOMEFILE
?依次讀取/PATH/FROM/SOMEFILE文件中的每一行,且將行賦值給變量line
?read 等待讀取鍵盤輸入,可以用管道,將命令的執(zhí)行結(jié)果逐行的賦值給read定義的變量

舉例

掃描/etc/passwd文件每一行,如發(fā)現(xiàn)描述信息字段為空,則填充用戶
名和單位電話為62985600,并提示該用戶的描述信息修改成功。
#!/bin/bash
while read line;do
   gecons=`echo $line |cut -d: -f5`
   username=`echo $line |cut -d: -f1`
   if [ -z $gecons ];then  ---表示空為真,空就執(zhí)行下面的操作,[ -n $gecons ]正好相反,表示非空為真
       chfn -f $username -p 62985600 $username &>/dev/null  ---chfn
命令可以修改用戶的描述信息,其中-f選項(xiàng)是添加描述信息中的用戶名,
-p選項(xiàng)是添加單位電話
         echo the $username finger is modify
   fi
    done < /etc/passwd   ---逐行的讀取這個(gè)文件中的每一行賦值給line

也可以用管道

檢查分區(qū)利用率,發(fā)現(xiàn)80%就報(bào)警,并且指出設(shè)備名
#!/bin/bash
df|grep '/dev/sd'|while read disk;do
           diskused=`echo $disk|sed -r 's/^.* ([0-9]{1,2})%.*$/\1/'`
           devname=`echo $disk|cut -d ' ' -f1`
         [ $diskused -gt 80 ]&& echo "$devname will be full:$diskused%"
done
  • 雙小括號(hào)用法

?雙小括號(hào)方法,即((…))格式,也可以用于算術(shù)運(yùn)算
?for循環(huán)的特殊格式:
for ((控制變量初始化;條件判斷表達(dá)式;控制變量的修正表達(dá)式))
do
循環(huán)體
done
?控制變量初始化:僅在運(yùn)行到循環(huán)代碼段時(shí)執(zhí)行一次
?控制變量的修正表達(dá)式:每輪循環(huán)結(jié)束會(huì)先進(jìn)行控制變量修正運(yùn)算,而后再做條件判斷

QQ截圖20170826140313.png

舉例

#!/bin/bash
for ((i=1,sum=0;i<=100;i++));do  ---執(zhí)行時(shí),控制變量的初始化就剛開(kāi)始時(shí)執(zhí)行一次,然后進(jìn)行判斷,進(jìn)入第一次循環(huán),循環(huán)結(jié)束之后,進(jìn)行變量的修正,讓i增加1,然后再進(jìn)行判斷,進(jìn)入第二輪循環(huán)
    let sum+=i
done
   echo "sum=$sum"
#!/bin/bash
sum=0
i=1
while ((i<=100));do
     let sum+=i
     let i++
done
    echo "sum=$sum"

7、select循環(huán)與菜單

?select variable in list
do
循環(huán)體命令
done
?select 循環(huán)主要用于創(chuàng)建菜單,按數(shù)字順序排列的菜單項(xiàng)將顯示在標(biāo)準(zhǔn)錯(cuò)誤上,并顯示PS3 提示符,等待用戶輸入
?用戶輸入菜單列表中的某個(gè)數(shù)字,執(zhí)行相應(yīng)的命令
?用戶輸入被保存在內(nèi)置變量REPLY 中
舉例

[root@redhat7 script]#select menus in lamian huimian yangtangmian yangroutang;do echo $menus;done
1) lamian
2) huimian
3) yangtangmian
4) yangroutang
#? 1    --輸入菜單中的某個(gè)數(shù)字,執(zhí)行do之后的命令
lamian
#? 
PS3=‘please choose your menu: '可以修改PS3提示符
[root@redhat7 script]#select menus in lamian huimian yangtangmian yangroutang;do echo $menus;done
1) lamian
2) huimian
3) yangtangmian
4) yangroutang
please choose your menu : 1
lamian
please choose your menu : 2
huimian
please choose your menu : 3
yangtangmian
please choose your menu : 4
yangroutang
please choose your menu : 1
lamian
please choose your menu : ---可以發(fā)現(xiàn)select循環(huán)是個(gè)無(wú)限循環(huán),不會(huì)退出
編寫(xiě)腳本實(shí)現(xiàn)點(diǎn)菜功能
#!/bin/bash
PS3='please choose your menu:'
select menu in lamimian huimian yangtangmian yangroutang yangpai;do ----用戶輸入菜單對(duì)應(yīng)的數(shù)字,會(huì)執(zhí)行do循環(huán)體內(nèi)的命令
case $REPLY in       ----用戶的輸入的數(shù)字被保存到REPLY變量中
1)
     echo "price is \$10"
         ;;
2)
     echo "price is \$15"
          ;;
3)
   echo "price is \$25"
       ;;
4)   echo "price is \$40"
        ;;
5)     echo "price is \$50"
                   ;;
*)     echo "get out!"
          break
esac
done

總結(jié):select 是個(gè)無(wú)限循環(huán),因此要記住用break 命令退出循環(huán),或用exit 命令終止腳本。也可以按ctrl+c 退出循環(huán),select 經(jīng)常和case 聯(lián)合使用。
PS1命令提示符
PS2多行重定向的命令提示符

8、信號(hào)捕捉trap

?trap '觸發(fā)指令' 信號(hào)
自定義進(jìn)程收到系統(tǒng)發(fā)出的指定信號(hào)后,將執(zhí)行觸發(fā)指令,而不會(huì)執(zhí)行原操作
?trap ' ' 信號(hào):忽略信號(hào)的操作
?trap '-' 信號(hào):恢復(fù)原信號(hào)的操作
?trap -p:列出自定義信號(hào)操作
?trap -l:查看都有哪些信號(hào)
舉例

[root@redhat7 script]#trap -l  ---查看信號(hào),2信號(hào)表示ctrl+c
 1) SIGHUP   2) SIGINT   3) SIGQUIT  4) SIGILL   5) SIGTRAP
 6) SIGABRT  7) SIGBUS   8) SIGFPE   9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG  24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF 28) SIGWINCH    29) SIGIO   30) SIGPWR
31) SIGSYS  34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX    
#!/bin/bash
trap 'echo "you are a baby"' int   ---注意int前面一定要有空格,這是一個(gè)坑,沒(méi)有空格腳本執(zhí)行有錯(cuò)誤,并且單引號(hào)里面要放命令,意思是執(zhí)行這個(gè)信號(hào)后會(huì)執(zhí)行什么命令
    trap -p    ---列出自定義的信號(hào)
for ((i=1;i<10;i++));do
      echo $i  
       sleep 0.5
done
[root@redhat7 script]#./trap.sh 
trap --'echo "you are a baby"' SIGINT  ---顯示出自定義的信號(hào)
1
2
^Cpress ctrl+c  ---原來(lái)按ctrl+c時(shí)就終止這個(gè)腳本,此時(shí)按ctrl+c不起
作用,不會(huì)終止腳本,而是在屏幕上打印一句話。
3
4
^Cyou are a baby
5
6
^Cyou are a baby
7
8
^Cyou are a baby
9
#!/bin/bash
trap '' int  ---雙引號(hào)中間什么也沒(méi)有表示忽略信號(hào)的操作,當(dāng)你按ctrl+c時(shí),不會(huì)停止腳本的運(yùn)行
for ((i=1;i<10;i++));do
      echo $i  
       sleep 1
done
#!/bin/bash
trap '-' int    ---雙引號(hào)中間放個(gè)-表示恢復(fù)信號(hào)的操作,此時(shí)再按ctrl+c就可以停止腳本了
for ((i=1;i<10;i++));do
      echo $i  
       sleep 1
done
#!/bin/bash
trap 'echo nozuonodi' term  ---換一個(gè)信號(hào),15信號(hào)是殺死進(jìn)程,信號(hào)的名字是sigterm,大小寫(xiě)都可以,也可以簡(jiǎn)寫(xiě)為term
trap -p
for ((i=1;i<100;i++));do
      echo $i  
       sleep 1
done
killall trap.sh    當(dāng)執(zhí)行這個(gè)命令時(shí),原操作是會(huì)殺死進(jìn)程,現(xiàn)在不可
以了,而是在屏幕上打印一句話nozuonodi
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 選擇執(zhí)行:if語(yǔ)句條件判斷:case語(yǔ)句循環(huán)控制:for語(yǔ)句循環(huán)控制:while語(yǔ)句和until語(yǔ)句循環(huán)控制:co...
    哈嘍別樣閱讀 459評(píng)論 0 1
  • 流程控制過(guò)程式編程語(yǔ)言:順序執(zhí)行選擇執(zhí)行循環(huán)執(zhí)行 一.條件選擇if語(yǔ)句 類型:選擇執(zhí)行 ?注意:if語(yǔ)句可嵌套 ?...
    楠人幫閱讀 573評(píng)論 0 1
  • linux資料總章2.1 1.0寫(xiě)的不好抱歉 但是2.0已經(jīng)改了很多 但是錯(cuò)誤還是無(wú)法避免 以后資料會(huì)慢慢更新 大...
    數(shù)據(jù)革命閱讀 13,207評(píng)論 2 33
  • 一個(gè)簡(jiǎn)單的搜索引擎 該搜索引擎具有以下功能:通過(guò)一個(gè)種子鏈接不斷爬取網(wǎng)頁(yè),可以指定爬取網(wǎng)頁(yè)的層數(shù),以此來(lái)控制搜索的...
    丁昆朋閱讀 306評(píng)論 0 0
  • 尊敬的各位領(lǐng)導(dǎo),各位老師,各位家長(zhǎng),親愛(ài)的同學(xué)們,大家好!今天我發(fā)言的題目是《爭(zhēng)做博雅教師,打造精品課堂,培養(yǎng)博...
    Yeah明珠閱讀 1,179評(píng)論 2 0

友情鏈接更多精彩內(nèi)容