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


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