bash腳本編程之條件判斷、算術運算及實例

bash中如何實現條件斷?

條件測試類型:

    整數測試

    字符測試

    文件測試

條件測試的表達式

    [ expression ],命令測試法

    [[ expression ]],關鍵字測試法

    test expression,test命令測試法

如何進行測試:

    整數測試

        -eq:測試兩個整數是否相等,相等爲真,不等爲假,如[ $a -eq $b ] ,如果相等,則執行狀態返回值一定爲0,否則爲1-255之間的任何一個值.

        -ne:測試兩個整數是否不相等,相等爲假,不等爲真

        -gt:測試一個數是否大於另一個數,大於爲真,否則爲假 

        -lt:測試一個數是否小於另一個數,小於爲真,否則爲假 

        -ge:測試一個數是否大於等於另一個數,大於等於爲真,否則爲假 

        -le:測試一個數是否小於等於另一個數,小於等於爲真,否則爲假

    命令之間邏輯關係測試

        邏輯與:如果其中一個爲假,則結果一定爲假,短路測試,第一個條件爲假時,不執行第二個條件;第一個條件爲真時,第二個條件必須執行

        如:查詢用戶存在並顯示信息        

        [root@station01 ~]# id user9 &>/dev/null && echo "user9 exist." 

        user9 exist.

        如:查詢用戶不存在就添加

        ! id user9 && useradd user9

        id user9 || useradd user9

        如:判斷一個文件的行數,如果大於100,則顯示爲大文件件        

        1)方法一

        [user9@station01 ~]$ [ `wc -l /etc/inittab |cut -d' ' -f1 ` -gt 100 ] && echo "/etc/inittab is a large file." || echo "A small file."

 

        A small file.

        2)方法二

        文件test2.sh內容如下:        

        [root@station01 ~]# cat test2.sh 
        #!/bin/bash
        #
        Linenum=`wc -l /etc/inittab | cut -d ' ' -f1 `
        #echo $Linenum
        [ $Linenum -gt 100 ] && echo "/etc/inittab is a large file." || echo "/etc/inittab is a small file."

        邏輯或:如果其中一個爲真,則結果一定爲真,短路測試

引用一個命令的執行結果,需要用命令替換

變量命名規則:變量只能包含字母、數字和下劃線,不能以數字開頭;並且不可以與系統中已有的環境變量名稱相同;見名知義


    如查用戶已存在,顯示此用戶存在,否則添加此用戶

    id user9 && echo "user9 exist." || useradd user9


    如查用戶不存在,添加用戶,否則顯示用戶已存在

    ! id user9 && useradd user9 || echo "user9 exsit."


    如果用戶不存在,添加並設置密碼,否則顯示已存在

    !id user9 && useradd user9 && echo "user9" | passwd --stdin user9 || echo "user9 exist"

    

    如果用戶不存在,添加用戶並設置與用戶名相同的密碼,如已存在顯示用戶已存;最後顯示系統中總共有多少個用戶

    test3.sh文件內容如下:

    [root@station01 ~]# cat test3.sh 
    #!/bin/bash
    #
    ! id user1 &>/dev/null && useradd user1 && echo "user1" | passwd --stdin user1 &>/dev/null || echo "user1 is exist."
    ! id user2 &>/dev/null && useradd user2 && echo "user2" | passwd --stdin user2 &>/dev/null || echo "user2 is exist."
    USERS=`wc -l /etc/passwd | cut -d' ' -f1`
    echo "$USERS users."

    執行結果如下:    

    [root@station01 ~]# ./test3.sh   

    user1 is exist.

    user2 is exist.

    41 users.

            

    給定一用戶,如果id爲0,則顯示爲管理員,否則爲普通用戶

    test4.sh文件內容如下:    

    [root@station01 ~]# cat test4.sh 
    #!/bin/bash
    #
    NAME=user1
    [ `id -u $NAME` -eq  0 ] && echo "$NAME is administrator." || echo "$NAME is a common user."


條件判斷的控制結構

單分支的if語句

    if 判斷條件;then

        語句1

        語句2

        ....

    fi

    如判斷給定用戶是否存在,如果存在則顯示已存在    

    [root@station01 ~]# cat test5.sh 
    #!/bin/bash
    #
    NAME=user1
    if id $NAME &>/dev/null;then
            echo "$NAME is esist."
    fi

雙分支的if語句

    if 判斷條件;then

        語句1

        語句2

        ...

    else

        語句1

        語句2

        ...

    fi

    如判斷給定用戶是否存在,如果存在則顯示已存在,否則顯示不存在

    [root@station01 ~]# cat test5.sh 

    #!/bin/bash
    #
    NAME=user1
    if id $NAME &>/dev/null;then
            echo "$NAME is esist."
    else
            echo "$NAME is not exist."
    fi

    如判斷給定用戶是否存在,如果存在則顯示已存在,否則顯示不存在,添加用戶並設置與用戶名相同的密碼,並顯示添加成功    

    [root@station01 ~]# ./test5.sh 
    user12 is esist.
    [root@station01 ~]# cat test5.sh   
    #!/bin/bash
    #
    NAME=user12
    if id $NAME &>/dev/null;then
            echo "$NAME is esist."
    else
            useradd $NAME
            echo $NAME |passwd --stdin $NAME &>/dev/null
            echo "Add $NAME is successfully."
    fi

多分支的if語句

    if 判斷語句;then

        語句1

        語句2

        ...

    elif判斷語句2;then

        語句1

        語句2

        ...

    elif判斷語句3;then

        語句1

        ...

    ...

    else

        語句1

        ...

    fi

測試腳本是否有語法錯誤

bash -n 腳本名

bash -x 腳本名,單步執行

條件判斷分爲執行狀態和執行結果判斷

    引用一個命令的執行結果,要使用命令引用;引用一個命令的執行狀態結果,一定不能用引用

    如判斷當前系統上是否有用戶的默認shell爲bash,如有則顯示有多少此類用戶,否則顯示沒有。  

    [root@station01 ~]# cat test6.sh 
    #!/bin/bash
    #
    grep "\<bash$" /etc/passwd &>/dev/null
    RETVAL=$?
    if [ $RETVAL -eq 0 ];then
            USERS=`grep "\<bash$" /etc/passwd |wc -l`
            echo "The total of $USERS users is default bash shell."
    else
            echo "No such user."
    fi

    如判斷當前系統上是否有用戶的默認shell爲bash,如有則顯示其中一個用戶名,否則顯示沒有。

    [root@station01 ~]# cat test7.sh 
    #!/bin/bash
    #
    grep "\<bash$" /etc/passwd &>/dev/null
    RETVAL=$?
    if [ $RETVAL -eq 0 ];then
            USERS=`grep "\<bash$" /etc/passwd |head -1 |cut -d: -f1`
            echo "The one of $USERS is /etc/passwd file."
    else
            echo "No such user."
    fi

    如:給定一個文件,判斷是否有空白行,如有則顯示有多少行,否則顯示沒有空白行

    [root@station01 ~]# cat test8.sh 
    #!/bin/bash
    #
    FILES=/etc/inittab
    grep "^$" $FILES &>/dev/null
    RETVAL=$?
    if [ $RETVAL -eq 0 ];then
            LINES=`grep "^$" $FILES |wc -l`
            echo "The total of $LINES line is blank."
    else
            echo "No such blank line."
    fi

    如:給定一用戶,判定其UID是否等於GID,如一樣,則顯示SAME,否則顯示NOT THE SAME    

    1)方法一

    [root@station01 ~]# cat test9.sh 
    #!/bin/bash
    #
    USERNAME=user1
    if [ `id -u $USERNAME` -eq `id -g $USERNAME` ];then
            echo "The ${USERNAME}'s UID equal GID."
    else
            echo "Not the same"
    fi

    2)方法二

    [root@station01 ~]# cat test10.sh 
    #!/bin/bash
    #
    USERNAME=user6
    if [ `grep "^\<$USERNAME\>" /etc/passwd | cut -d: -f3` -eq `grep "^\<$USERNAME\>" /etc/passwd | cut -d: -f4` ];then
            echo "The ${USERNAME}'s UID equal GID."
    else
            echo "Not the same"
    fi

SHELL中如何進行算術運算

    1、定義變量時爲字符型,運算時用let命令;

       let 算術運算表達式,let CC=$AA+$BB

       如:

        [root@station01 ~]# AA=1
        [root@station01 ~]# BB=2
        [root@station01 ~]# let CC=$AA+$BB
        [root@station01 ~]# echo $CC
        3

    2、$[算術運算表達式]

        

        CC=$[$AA+$BB]

    3、$((算術運算表達式))

       

        CC=$(($AA+$BB))

    4、expr 算術運算表達式,表達式中各操作數及運算符之間有空格,而且要使用命令引用

       

        CC=`expr $AA + $BB`

退出當前進程命令

    exit:退出腳本,用於定義執行狀態結果的命令。用法:exit 0-255之間的任一數值,如腳本未定義腳本退出碼,則最後一條命令執行的即爲腳本的退出碼。

    如判斷用戶是否存在,如已存在則提前退出腳本,否則執行

    

    [root@station01 ~]# cat test5.sh 
    #!/bin/bash
    #
    NAME=user12
    if ! grep "^$NAME/>" /etc/passwd &>/dev/null;then
            echo "$NAME is exsit"
            exit 23
    fi
    
    if id $NAME &>/dev/null;then
            echo "$NAME is esist."
    else
            useradd $NAME
            echo $NAME |passwd --stdin $NAME &>/dev/null
            echo "Add $NAME is successfully."
    fi

    執行結果:   

    

    [root@station01 ~]# ./test5.sh     
    user12 is exsit
    [root@station01 ~]# echo $?
    23


例:給定一用戶,獲取其密碼使用期限和密碼剩餘期限,判斷用戶密碼剩餘期限是否小於警告期限,如小於則提示“Warning”,否則“OK”

    密碼使用期限=當前時間-密碼修改時間

    密碼剩餘期限=密碼最長使用期限-密碼使用期限

/etc/shadow文件說明:

    Linux /etc/shadow文件中的記錄行與/etc/passwd中的一一對應,它由pwconv命令根據/etc/passwd中的數據自動產生。它的文件格式與/etc/passwd類似,由若干個字段組成,字段之間用“:”隔開。這些字段是:

登錄名:加密口令:最後一次修改時間:最小時間間隔:最大時間間隔:警告時間:不活動時間:失效時間:標誌

    1)“登錄名”是與/etc/passwd文件中的登錄名相一致的用戶賬號

    2)“口令”字段存放的是加密後的用戶口令字,長度爲13個字符。如果爲空,則對應用戶沒有口令,登錄時不需要口令;如果含有不屬於集合{./0-9A-Za-z}中的字符,則對應的用戶不能登錄。

    3)“最後一次修改時間”表示的是從某個時刻起,到用戶最後一次修改口令時的天數。時間起點對不同的系統可能不一樣。例如在SCOLinux中,這個時間起點是1970年1月1日。

    4)“最小時間間隔”指的是兩次修改口令之間所需的最小天數。

    5)“最大時間間隔”指的是口令保持有效的最大天數。

    6)“警告時間”字段表示的是從系統開始警告用戶到用戶密碼正式失效之間的天數。

    7)“不活動時間”表示的是用戶沒有登錄活動但賬號仍能保持有效的最大天數。

    8)“失效時間”字段給出的是一個絕對的天數,如果使用了這個字段,那麼就給出相應賬號的生存期。期滿後,該賬號就不再是一個合法的賬號,也就不能再用來登錄了。  


[root@station01 ~]# cat test12.sh 
        #!/bin/bash
        #
        USERNAME="root"
        WARNING=`grep "$USERNAME\>" /etc/shadow- | cut -d: -f6`
        CHANGETIME=`grep "$USERNAME\>" /etc/shadow- | cut -d: -f3`
        LANGDAY=`grep "$USERNAME\>" /etc/shadow- | cut -d: -f5`
        CURSECOND=`date +%s`
        #one:第一種算術運算
        let CURDAY=$CURSECOND/86400
        #two: 第二種算術運算
        PASSDAY=`expr $CURDAY - $CHANGETIME`
        #three:第三種運算
        LASTDAY=$[$LANGDAY-$PASSDAY]
        #four:第四種運算
        #LASTDAY=$(($LANGDAY-$PASSDAY))
        if [ $LASTDAY -lt $WARNING ];then
                echo "Waring,....."
        else
                echo "OK,......."
        fi
        
        #echo $WARNING
        #echo $CHANGETIME
        #echo $CURSECOND
        #echo $CURDAY
        #echo $PASSDAY
        #echo $LASTDAY

文件測試

屬於單目運算

-e FILE:文件名或文件路徑,測試文件是否存在

-f FILE:文件名或文件路徑,測試文件是否爲普通文件

-d FILE:文件名或文件路徑,測試指定路徑是否爲目錄

-r FILE:測試指定文件對當前用戶是否有讀權限

-w FILE:測試指定文件對當前用戶是否有寫權限

-x FILE:測試指定文件對當前用戶是否有執行權限


    如測試文件是否存在

    [ -e /etc/inittab ]

    測試文件是否有執行權限

    [ -x /etc/rc.d/rc.sysinit ]

    如測試文件是否存在,並是否有空白行

   [root@station01 ~]# cat test8.sh 
    #!/bin/bash
    #
    FILES=/etc/inittabaa
    if [ ! -e $FILES ];then
            echo "No such file."
            exit 20
    fi
    grep "^$" $FILES &>/dev/null
    RETVAL=$?
    if [ $RETVAL -eq 0 ];then
            LINES=`grep "^$" $FILES |wc -l`
            echo "The total of $LINES line is blank."
    else
            echo "No such blank line."
    fi

    執行結果

       

    [root@station01 ~]# ./test8.sh   
    No such file.
    [root@station01 ~]# echo $?
    20

    給定一個文件,如是一個普通文件,就顯示普通文件,如是一個目錄,就顯示爲目錄,否則無法識別,判斷文件是否存在,不存在則退出。

        

[root@station01 ~]# ./test13.sh 
        Common file...
        [root@station01 ~]# cat test13.sh 
        #!/bin/bash
        #
        FILES=/etc/rc.d/rc.sysinit
        #單分支if語句,判斷文件是否存在
        if [ ! -e $FILES ];then
                echo "No such file..."
                exit 24
        fi
        #多分支的if語句
        if [ -f $FILES ];then
                echo "Common file..."
        elif [ -d $FILES ];then
                echo "Directory .."
        else
                echo "Unknown."
        fi

GB-2312


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章