设为首页 收藏本站
查看: 574|回复: 0

[经验分享] bash脚本编程之条件判断、算术运算及实例

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-3-2 08:39:02 | 显示全部楼层 |阅读模式
bash中如何实现条件断?

条件测试类型:

    整数测试

    字符测试

    文件测试

条件测试的表达式
    [ expression ],命令测试法

    [[ expression ]],关键字测试法

    test expression,test命令测试法
如何进行测试:
    整数测试

        -eq:测试两个整数是否相等,相等为真,不等为假,如[ $a -eq $b ] ,如果相等,则执行状态返回值一定为0,否则为1-255之间的任何一个值.

        -ne:测试两个整数是否不相等,相等为假,不等为真

        -gt:测试一个数是否大于另一个数,大于为真,否则为假

        -lt:测试一个数是否小于另一个数,小于为真,否则为假
        -ge:测试一个数是否大于等于另一个数,大于等于为真,否则为假

        -le:测试一个数是否小于等于另一个数,小于等于为真,否则为假

    命令之间逻辑关系测试

        逻辑与:如果其中一个为假,则结果一定为假,短路测试,第一个条件为假时,不执行第二个条件;第一个条件为真时,第二个条件必须执行
        如:查询用户存在并显示信息       
        [iyunv@station01 ~]# id user9 &>/dev/null && echo "user9 exist."
        user9 exist.
       如:查询用户不存在就添加

        ! id user9 && useradd user9

        id user9 || useradd user9

       如:判断一个文件的行数,如果大于100,则显示为大文件件       
        1)方法一
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内容如下:        
1
2
3
4
5
6
        [iyunv@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文件内容如下:
1
2
3
4
5
6
7
    [iyunv@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."



    执行结果如下:   
    [iyunv@station01 ~]# ./test3.sh   
    user1 is exist.
    user2 is exist.
    41 users.

    给定一用户,如果id为0,则显示为管理员,否则为普通用户

    test4.sh文件内容如下:   
1
2
3
4
5
    [iyunv@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

    如判断给定用户是否存在,如果存在则显示已存在   
1
2
3
4
5
6
7
    [iyunv@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

    如判断给定用户是否存在,如果存在则显示已存在,否则显示不存在
    [iyunv@station01 ~]# cat test5.sh
1
2
3
4
5
6
7
8
    #!/bin/bash
    #
    NAME=user1
    if id $NAME &>/dev/null;then
            echo "$NAME is esist."
    else
            echo "$NAME is not exist."
    fi



    如判断给定用户是否存在,如果存在则显示已存在,否则显示不存在,添加用户并设置与用户名相同的密码,并显示添加成功    
1
2
3
4
5
6
7
8
9
10
11
12
13
    [iyunv@station01 ~]# ./test5.sh
    user12 is esist.
    [iyunv@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,如有则显示有多少此类用户,否则显示没有。  
1
2
3
4
5
6
7
8
9
10
11
    [iyunv@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,如有则显示其中一个用户名,否则显示没有。
1
2
3
4
5
6
7
8
9
10
11
    [iyunv@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



    如:给定一个文件,判断是否有空白行,如有则显示有多少行,否则显示没有空白行
1
2
3
4
5
6
7
8
9
10
11
12
    [iyunv@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)方法一
1
2
3
4
5
6
7
8
9
    [iyunv@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)方法二
1
2
3
4
5
6
7
8
9
    [iyunv@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

       如:
1
2
3
4
5
        [iyunv@station01 ~]# AA=1
        [iyunv@station01 ~]# BB=2
        [iyunv@station01 ~]# let CC=$AA+$BB
        [iyunv@station01 ~]# echo $CC
        3



    2、$[算术运算表达式]

1
        CC=$[$AA+$BB]



    3、$((算术运算表达式))

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



    4、expr 算术运算表达式,表达式中各操作数及运算符之间有空格,而且要使用命令引用

1
        CC=`expr $AA + $BB`



退出当前进程命令
    exit:退出脚本,用于定义执行状态结果的命令。用法:exit 0-255之间的任一数值,如脚本未定义脚本退出码,则最后一条命令执行的即为脚本的退出码。
    如判断用户是否存在,如已存在则提前退出脚本,否则执行


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    [iyunv@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



    执行结果:   

1
2
3
4
    [iyunv@station01 ~]# ./test5.sh     
    user12 is exsit
    [iyunv@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)“失效时间”字段给出的是一个绝对的天数,如果使用了这个字段,那么就给出相应账号的生存期。期满后,该账号就不再是一个合法的账号,也就不能再用来登录了。  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
[iyunv@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 ]

    如测试文件是否存在,并是否有空白行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
   [iyunv@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



    执行结果
       
1
2
3
4
    [iyunv@station01 ~]# ./test8.sh   
    No such file.
    [iyunv@station01 ~]# echo $?
    20



    给定一个文件,如是一个普通文件,就显示普通文件,如是一个目录,就显示为目录,否则无法识别,判断文件是否存在,不存在则退出。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[iyunv@station01 ~]# ./test13.sh
        Common file...
        [iyunv@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

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-42854-1-1.html 上篇帖子: Python批量修改文件格式 下篇帖子: 文本文件查找,正则 sed awk
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表