循環以及條件測試

條件測試:


        界定程序執行環境;(本質是斷定程序是否執行)node

        (1) 根據運行的命令的狀態結果斷定;    
            例如 id root &>/dev/null 等    
       
        (2) 測試表達式    
            test EXPRESSION    
            [ EXPRESSION ]    
            ` EXPRESSION `(建議多多使用此[[]],測試表達式和[]必須有空格)git

        整數測試:隱含着作數值大小比較,因此不要給變量引用加引用;    
            $A -gt $B:是否大於;是則爲「真」,不然爲「假」;    
            $A -ge $B: 是否大於等於;    
            $A -lt $B:是否小於;    
            $A -le $B: 是否小於等於;    
            $A -eq $B: 是否等於;    
            $A -ne $B:是否不等於;bash

        字符串測試:ASCII數值越大,字符比較時其值越大;    
            "$A" > "$B":是否大於;    
            "$A" < "$B":是否小於;    
            "$A" == "$B":是否等於;    
            "$A" != "$B":是否不等於;    
            -z "$A":是否爲空;空則爲「真」,不然爲「假」    
            -n "$A":是否不空;不空則「真」,空則爲「假」ide

            若是首字符相同則比較第二個字符以此類推    
            注意:應該使用` EXPRESSION `測試

        文件測試:測試文件的存在性以及屬性;    
            -e $file: 是否存在;存在則爲「真」,不然爲「假」;    
            -a $file: 同上;    
            -f $file:文件是否存在且爲普通文件;    
            -d $file:文件是否存在且爲目錄;    
            -h $file:是否存在且爲符號連接文件;    
            -L $file: 同上    
            -b $file:是否存在且爲塊設備文件;    
            -c $file:是否存在且爲字符設備文件;    
            -S $file:是否存在且爲套接字文件;    
            -p $file: 是否存在且爲管道文件;spa

            -r $file: 當前用戶對文件是否擁有讀權限;    
            -w $file:當前用戶對文件是否擁有寫權限;    
            -x $file:當前用戶對文件是否擁有執行權限;rest

            -u $file:文件是否擁有SUID權限;    
            -g $file:文件是否擁有SGID權限;    
            -k $file:文件是否擁有sticky權限;ci

            -O $file: 當前用戶是否爲指定文件的屬主;    
            -G $file: 當前用戶是否爲指定文件的屬組;字符串

            雙目操做符:    
            $file1 -nt $file2: file1是否新於file2, file1的最近一次的修改時間戳是否晚於file2             的;    
            $file1 -ot $file2: file1是否舊於file2, file1的最近一次的修改時間戳是否早於file2             的;    
            $file1 -ef $file2:file1與file2是否指向了同一個inode;測試兩者是否爲同一個文件             的硬連接;it

bash之條件判斷(選擇執行):      
        if/then, case

        if CONDITION; then      
            if-true-分支(condition斷定爲真執行該段)      
        fi

        if CONDITION; then      
            if-true-分支      
        else      
            if-false-分支(condition斷定爲假執行該段)      
        fi

        ! CONDITION: 取反


    練習:寫一個腳本      
        若是某路徑不存在,則將其建立爲目錄;不然顯示其存在,並顯示內容類型;      

#!/bin/bash       
#       
filename="/tmp/x/y/z/testdir"       
if [ -e $filename ]; then          ##斷定變量filename的變量值是否存在       
   echo "$filename exists."       
   file $filename                      ##存在則執行以上兩行操做       
else                                           ##不存在執行以下操做       
   mkdir -p $filename       
   fi

練習:寫一個腳本,完成以下功能;      
        判斷給定的兩個數值,孰大孰小;      
            給定數值的方法:腳本參數,命令交互;

#!/bin/bash      
#       
read -p "Plz enter two integer: " -t 10 num1 num2   
##與用戶以交互方式 賦值變量num1 變量num2
if [ -z "$num1" ]; then                      
   echo "Plz give two integers."       
   exit 1                       ##斷定第一個參數是否爲空 是則提示並退出腳本      
fi
if [ -z "$num2" ]; then      
   echo "Plz give tow integers."       
   exit 1                       ##斷定第一個參數是否爲空 是則提示並退出腳本       
fi
if [ $num1 -ge $num2 ]; then    ##斷定變量num1的變量值是否大於變量num2的變量值      
   echo "Max: $num1, Min: $num2."         ##變量num1大則執行此命令                                                                      
   else       
   echo "Max: $num2, Min: $num1."         ##變量num1小則執行此命令       
fi

多分支的if語句:      
    單分支:      
        if CONDITION; then      
            if-true-分支      
        fi

    雙分支:      
        if CONDITION; then      
            if-true-分支    ()   
        else      
            if-false-分支      
        fi

    多分支:用於須要對多種狀況斷定是否執行時使用      
        if CONDITION1; then      
            if-CONDITION1-true-分支      
        elif CONDTION2; then      
            if-CONDITIO2-true-分支      
        ...      
        else      
            if-ALL-false-分支      
        fi

        示例:經過腳本參數傳遞一個文件路徑給腳本,判斷其類型;(文件只會符合一個斷定條件)      

#!/bin/bash       
 #       
if [ $# -lt 1 ]; then       
    echo "Usage: $0 <path>"       
    exit 1       
fi                ##以上檢測至少要有一個參數傳遞給腳本 不然腳本結束
if [ -f $1 ]; then                               
     echo "Rgular file."      ##傳遞的第一個參數是存在並且是普通文件       
elif [ -d $1 ]; then       
   echo "Directory."          ##傳遞的第一個參數是存在並且是目錄文件       
elif [ -h $1 ]; then       
   echo "Symbolic link."     ##傳遞的第一個參數是存在並且是符號連接文件       
elif [ -b $1 ]; then       
   echo "Block special."      ##傳遞的第一個參數是存在並且是塊文件       
elif [ -c $1 ]; then       
   echo "Charactoer special."   ##傳遞的第一個參數是存在並且是字符文件       
elif [ -S $1 ]; then       
   echo "Socket file."          ##傳遞的第一個參數是存在並且是套接字文件       
else       
   echo "file not exist or unknown type."    ##以上斷定都不是則執行此命令       
fi

        

     示例:腳本可接受四個參數      
            start: 建立文件/var/lock/subsys/SCRIPT_NAME      
            stop: 刪除此文件      
            restart: 刪除此文件並從新建立      
            status: 若是文件存在,顯示爲"running",不然,顯示爲"stopped"

            basename命令:      
                取得路徑的基名;

#!/bin/bash      
#       
prog=$(basename $0)               ##取得腳本路徑的基名賦值給變量prog       
lockfile="/var/lock/subsys/$prog"          ##生產新的路徑賦值給變量lockfile       
#echo $lockfile
if [ $# -lt 1 ]; then      
   echo "Usage: $prog start|stop|restart|status"       
   exit 1       
fi             ##斷定必須有至少一個參數傳遞給腳本
if [ "$1" == "start" ]; then      
   if [ -f $lockfile ]; then       
      echo "$prog is started yet."            
      ##斷定傳遞來的參數是start 且$lockfile是普通文件則顯示腳本is started yet       
   else       
      touch $lockfile && echo "Starting $prog ok..." || echo "Starting $prog failed..."
      ##斷定傳遞來的參數是start 且$lockfile不存在,則建立$lockfile文件建立成功後顯示Starting $prog ok.,若是建立失敗則顯示啓動失敗      
fi       
elif [ "$1" == 'stop' ]; then       
   if [ -f $lockfile ]; then       
     rm -f $lockfile && echo "Stop $prog ok...." || echo "Stop $prog failed..."
     ##斷定傳遞來的參數是stop且$lockfile是普通文件則強制刪除$lockfile刪除成功後顯示Stop $prog ok....",若是刪除失敗則顯示中止失敗
   else      
   echo "$prog is stopped yet."
##斷定傳遞來的參數是stop且$lockfile不存在則顯示$prog(取變量值 )is stopped yet    
fi       
elif [ "$1" == 'restart' ]; then       
   if [ -f $lockfile ]; then       
      rm -f $lockfile && touch $lockfile && echo "Restarting $porg ok..."
      ##斷定傳遞來的參數是restart且$lockfile是普通文件則強制刪除$lockfile刪除成功後建立新的$lockfile,建立成功後顯示Restarting $porg ok      
   else       
     touch $lockfile && echo "$prog is stopped, Starting $prog ok...."
     ##斷定傳遞來的參數是restart且$lockfile不存在則建立新的$lockfile,建立成功後顯示$prog is stopped, Starting $prog ok              
fi      
elif [ "$1" == 'status' ]; then       
   if [ -f $lockfile ]; then       
     echo "Running..."
     ##斷定傳遞來的參數是status且$lockfile是普通文件則顯示正在運行      
   else       
     echo "Stopped..."
     ##斷定傳遞來的參數是status且$lockfile不存在則顯示已經中止      
fi       
else       
    echo "Usage: $prog start|stop|restart|sttus"       
    exit 1
    ##斷定如傳遞來的參數不是start|stop|restart|sttus,則提示Usage: $prog start|stop|restart|sttus,而後錯誤結束腳本      
fi


case語句      
    簡潔版多分支if語句;               
    使用場景:判斷某變量的值是否爲多種情形中的一種時使用;

    語法:      
        case $VARIABLE in      
        PATTERN1)      
            分支1      
            ;;                 ##斷定$VARIABLE符合PATTERN1則執行分支1命令

        PATTERN2)      
            分支2      
            ;;                ##斷定$VARIABLE符合PATTERN2則執行分支2命令      
        PATTERN3)      
            分支3      
            ;;                ##斷定$VARIABLE符合PATTERN3則執行分支3命令      
        ...      
        *)      
            分支n      
            ;;                ##斷定$VARIABLE符合PATTERNn則執行分支n命令      
        esac

        PATTERN可以使用glob模式的通配符:      
            *: 任意長度的任意字符;      
            ?: 任意單個字符;      
            []: 指定範圍內的任意單個字符;      
            a|b: 多選1;

        示例:提示鍵入任意一個字符;判斷其類型;      

#!/bin/bash       
#       
read -p "Plz enter a character: " char   
##提示輸入一個字符 用交互方式複製給變量char
case $char in      
[a-z])                   ##輸入的爲一個字母則顯示爲字母       
    echo "A character."       
    ;;       
[0-9])       
    echo "A digit."      ##輸入的爲一個數字則顯示爲數字       
    ;;       
*)       
     echo "A special character."      ##若是以上匹配不到,且輸入的是任意長度的任意字符則顯示爲特殊字符       
    ;;       
esac

          

      示例:腳本可接受四個參數      
            start: 建立文件/var/lock/subsys/SCRIPT_NAME      
            stop: 刪除此文件      
            restart: 刪除此文件並從新建立      
            status: 若是文件存在,顯示爲"running",不然,顯示爲"stopped"

#!/bin/bash      
#       
prog=$(basename $0)       
lockfile="/var/lock/subsys/$prog"       
#echo $lockfile
if [ $# -lt 1 ]; then      
   echo "Usage: $prog start|stop|restart|status"       
   exit 1       
fi
case $1 in      
   start)       
   if [ -f $lockfile ]; then       
      echo "$prog is started yet."
##斷定傳遞來的參數是start 且$lockfile是普通文件則顯示腳本is started yet      
   else       
      touch $lockfile && echo "Starting $prog ok..." || echo "Starting $prog failed..."
   ##斷定傳遞來的參數是start 且$lockfile不存在,則建立$lockfile文件建立成功後顯示Starting $prog ok.,若是建立失敗則顯示啓動失敗      
fi       
;;       
   stop)       
   if [ -f $lockfile ]; then       
     rm -f $lockfile && echo "Stop $prog ok...." || echo "Stop $prog failed..."
   ##斷定傳遞來的參數是stop且$lockfile是普通文件則強制刪除$lockfile刪除成功後顯示Stop $prog ok....",若是刪除失敗則顯示中止失敗      
   else       
      echo "$prog is stopped yet."
   ##斷定傳遞來的參數是stop且$lockfile不存在則顯示$prog(取變量值 )is stopped yet      
   fi       
;;       
   restart)       
   if [ -f $lockfile ]; then       
      rm -f $lockfile && touch $lockfile && echo "Restarting $porg ok..."
   ##斷定傳遞來的參數是restart且$lockfile是普通文件則強制刪除$lockfile刪除成功後建立新的$lockfile,建立成功後顯示Restarting $porg ok      
   else       
      touch $lockfile && echo "$prog is stopped, Starting $prog ok...."
   ##斷定傳遞來的參數是restart且$lockfile不存在則建立新的$lockfile,建立成功後顯示$prog is stopped, Starting $prog ok      
   fi       
;;       
   status)       
   if [ -f $lockfile ]; then       
      echo "Running..."       
      ##斷定傳遞來的參數是status且$lockfile是普通文件則顯示正在運行      
   else       
      echo "Stopped..."
   ##斷定傳遞來的參數是status且$lockfile不存在則顯示已經中止      
   fi       
;;       
   *)       
      echo "Usage: $prog start|stop|restart|sttus"       
      exit 1
      ##斷定如傳遞來的參數不是start|stop|restart|sttus,則提示Usage: $prog start|stop|restart|sttus,而後錯誤結束腳本      
esac


循環語句:


        for, while, until

        循環:將循環體代碼執行0、1或屢次;    
            進入條件:進入循環的條件;    
            退出條件:循環終止的條件;    
       
        格式:    
        for VARIABLE in LIST; do    
            循環體    
        done

        LIST:是由一個或多個空格或換行符分隔開的字符串組成;    
            把列表的每一個字符串逐個賦值給VARIABLE表示的變量;

            for username in user1 user2 user3; do    
                循環體    
            done

            進入條件:列表非空;    
            退出條件:列表遍歷結束;

            添加10個用戶,user1-user10;

               

 #!/bin/bash    
 #     
 for username in user1 user2 user3 user4 user5; do          ##循環進入標記列表仍有能夠賦值,結束條件爲列表參數所有賦值過     
   if id $username &> /dev/null; then     
       echo "$username exists."     
   else     
       useradd $username     
       echo "Add user $username finished."     
   fi     
done

            LIST的生成方法:    
                (1) 整數列表    
                    (a) {start..end}    
                    (b) $(seq [start `step` end)    
                (2) 直接給出列表  例如for username in user1 user2 user3 user4 user5    
                (3) glob (bash通配)例如 for file in /etc/f*    
                (4) 命令生成          for file in $(ls /mnt)

                示例:數值列表    

                    #!/bin/bash     
                    #     
                    for i in {1..10}; do              ##直接給出列表     
                        if id user$i &> /dev/null; then     
                        echo "user$i exists."     
                        else     
                        useradd user$i     
                            echo "Add user user$i finished."     
                        fi     
                    done

                示例:glob    

                    #!/bin/bash     
                    #     
                    for filename in /var/log/*; do         ##輪值爲/var/log下的全部文件     
                        file $filename     
                    done

                示例:命令生成列表    

                    #!/bin/bash     
                    #     
                    for username in $(cut -d: -f1 /etc/passwd); do          ##命令引用取列表爲系統中的全部用戶     
                        echo "$username primary group: $(id -n -g $username)."     
                    done

                示例:求100之內因此正整數之和;    

            #!/bin/bash                 
            #                 
            declare -i sum=0
            for i in {1..100}; do         變量i的變量值輪1到100                   
               sum=$[$sum+$i]         ##將變量sum的變量值加上變量i的變量值所得值再從新賦值變量sum    
            done
            echo $sum

示例:顯示/etc目錄下全部普通文件列表,然後統計一共有多少個文件;

        #!/bin/bash            
        #             
        declare -i count=0                  ##定義計數器 整型變量count
        for file in /etc/*; do              ##使用通配方法生產/etc文件目錄下的文件列表                if [ -f $file ]; then                                     
             let count++                ##當是普通文件時計數器變量count本身+1                     echo "$count $file"                 
             fi             
        done
        echo "Total: $count files."

示例:寫一個腳本實現以下功能;    
            獲取當前主機的主機名;    
                若是當前主機的主機名爲空,或者爲localhost,則將其修改成www.magedu.com    
           

#!/bin/bash                 
#                 
hostname=$(hostname)            ##命令引用取得命令執行結果賦值給變量hostname
if [ -z "$hostname" -o "$hostname" == "localhost" ]; then   ##或表達式組合運用              hostname www.magedu.com                 
fi

       

        練習:寫一個腳本,打印九九乘法表;

            循環嵌套

            1X1=1    
            1X2=2 2X2=4    
            1X3=3 2X3=6 3X3=9

            #!/bin/bash    
            #     
            for j in {1..9}; do     
                for i in $(seq 1 $j); do   ##雙循環嵌套使用 保證被乘數不得大於乘數     
                    echo -n -e "${i}X${j}=$[$i*$j]\t"        
                done     
                echo     
            done

循環語句:for, while, until

        while循環:

            while CONDTION; do    
                循環體    
            done

            進入條件:當CONDITION爲「真」;    
            退出條件:當CONDITION爲「假」;

            while CONDITION; do    
                循環體    
                控制變量的修正表達式 (若是沒有修正變量可能會死循環)    
            done

            示例:求100之內全部正整數之和;

                #!/bin/bash                    
                #                     
                declare -i sum=0                     
                declare -i i=1
                while [ $i -le 100 ]; do                        
                   let sum+=$i                         
                   let i++                     
                done
                echo "Sum: $sum."

            練習:分別求100之內全部奇數之和,及全部偶數之和;

#!/bin/bash
#
declare -i sum1=0
declare -i sum2=0
declare -i i=0
while [ $i -le 100 ]; do
        if [ $[${i}%2] -eq 0 ]; then
          let sum1+=$i
        else
          let sum2+=$i
        fi
        let i++
done
echo "qishu sum $sum2"
echo "oushu sum $sum1"

            示例:打印九九乘法表    
               

#!/bin/bash                     
#                     
declare -i i=1                     
declare -i j=1
while [ $j -le 9 ]; do                       
    while [ $i -le $j ]; do                             
      echo -e -n "${i}X${j}=$[$i*$j]\t"                             
      let i++                         
    done                         
    echo                         
    let i=1                         
    let j++                     
done

        unitl循環:    
            until CONDITION; do    
                循環體    
                循環控制變量的修正表達式    
            done

            進入條件:當CONDITION爲「假」時    
            退出條件:當CONDITION爲「真」時

            示例:求100之內全部正整數之和    

                #!/bin/bash                     
                #                     
                declare -i sum=0                     
                declare -i i=1
                until [ $i -gt 100 ]; do                        
                   let sum+=$i                         
                   let i++                     
                done
                echo "Sum: $sum."

            練習1:分別求100之內全部偶數之和,以及全部奇數之和;

    

#!/bin/bash
#
declare -i sum1=0
declare -i sum2=0
declare -i i=0
until  [ $i -gt 100 ]; do
        if [ $[${i}%2] -eq 0 ]; then
          let sum1+=$i
        else
          let sum2+=$i
        fi
        let i++
done
echo "qishu sum $sum2"
echo "oushu sum $sum1"

            練習2:實現九九乘法表; 

#!/bin/bash
#
#!/bin/bash
#
declare -i i=1
declare -i j=1
until  [ $i -gt 9 ]; do
       until [ $j -gt $i ]; do
         echo -n "${j}x${i}=$[$j*$i] "
         let j++
       done
         let j=1
         let i++
        echo
done

   
            練習3:分別使用while和until循環實現添加10個用戶:user1-user10;

#!/bin/bash
#
declare -i i=1
while [ $i -le 10 ]; do
        useradd user${i}
        let i++
done
#!/bin/bash
#
declare -i i=1
until [ $i -gt 10 ];do
         useradd user${i}
        let i++
done


        循環控制:    
            continue [n]:提早結束本輪循環,而直接進入下一輪;    
            break [n]:提早結束循環;

            while循環:    
                while CONDITION; do    
                    .......    
                    if CONDITION2; then    
                        break [n]    
                    fi    
                done

                while CONDITION; do    
                    ......    
                    if CONDITION2; then    
                        continue [n]    
                    fi    
                    ......    
                done

            示例:求100之內全部偶數之和;

                #!/bin/bash                    
                #                     
                declare -i sum=0                     
                declare -i i=0
                while [ $i -le 100 ]; do                        
                    let i++                         
                   if [ $[$i%2] -eq 1 ]; then                         
                      echo "$i is a odd."                             
                      continue                         
                   fi                         
                    let sum+=$i                     
                done
                echo "Sum: $sum."

        死循環:    
            while true; do    
                循環體    
                if CONDTION; then    
                    break    
                fi    
            done

            until false; do    
                循環體    
                if CONDITION; then    
                    break    
                fi    
            done

            示例:每隔3秒鐘查看當前系統上是否有名爲「gentoo」的用戶登陸;    
                若是某次查看gentoo登陸了,則顯示gentoo已經登陸;    
                若是未登陸,就顯示仍然將來,並顯示這是已是第多少次查看了;

              

  #!/bin/bash                    
  #                     
  username=$1                     
  declare -i count=0
  while true; do                        
      if who | grep "^$username" &> /dev/null; then                             
          echo "$username is logged."                              
          break                       
      else                               
          let count++                             
          echo "$count $username is not login."                         
      fi                         
      sleep 3                     
      done


               

#!/bin/bash                     
#                     
declare -i count=0                     
username=$1
if [ $# -lt 1 ]; then                        
         echo "At lease one argument."                         
         exit 1                     
         fi
if ! id $username &> /dev/null; then                        
         echo "No such user."                         
         exit 2                     
         fi
until who | grep "^$username" &> /dev/null; do                        
       let count++                         
       echo "$count $username is not login."                         
       sleep 3                     
       done
echo "$username is logged on."

        while循環的特殊用法:    
            遍歷文件的每一行:    
                while read VARIABLE; do    
                    循環體    
                done < /PATH/FROM/SOME_FILE

            示例:找出UID爲偶數的全部用戶,顯示其用戶名和ID號;    

                #!/bin/bash     
                #     
                while read line; do     
                    userid=$(echo $line | cut -d: -f3)     
                    if [ $[$userid%2] -eq 0 ]; then     
                        echo $line | cut -d: -f1,3     
                    fi     
                done < /etc/passwd

        for循環的特殊用法:    
            for ((expr1;expr2;expr3)); do    
                循環體    
            done

            expr1: 定義控制變量,並初始賦值;    
            expr2: 循環控制條件;    
                進入條件:控制條件爲「真」    
                退出條件:控制條件爲「假」    
            expr3: 修正控制變量

            示例:求100之內全部正整數之和;    

                #!/bin/bash                     
                #                     
                declare -i sum=0
                for ((i=1;i<=100;i++)); do                        
                  let sum+=$i                     
                done
                echo "Sum: $sum."

               

            練習1:打印九九乘法表;   

#!/bin/bash
#
for (( i=1;i<10;i++));do
        for (( j=1;j<=i;j++));do
            echo -n "${j}x$i=$[ $j*$i ] "
        done
        echo
done

 
            練習2:傳遞一個文本文件爲參數給腳本,取出此文件的全部的偶數行給予顯示,行前要顯示行號;

#!/bin/bash
#
if [ $# -lt 1 ]; then
  echo " must ernter /path/to/somefile "
  exit 1
fi
j=$(wc -l $1 | cut -d" " -f1 )
if [ -f $1 ]; then
  for (( i=1;i<=j ;i++  ));do
        if [ $[${i}%2] -eq 0 ];then
          echo -n "$i  "
           head -$i $1 | tail -1
        fi
  done
fi
相關文章
相關標籤/搜索