bash之条件测试if/else

bash之条件测试:
    if/then结构
   
    条件测试(CONDITION):
        test EXPRESSION:测试条件表达式正确否
        [ EXPRESSION ]
        [[ EXPRESSION ]]
        COMMAND
       
    测试表达式:
        1)整数测试
        2)字符串测试
        3)文件测试
       
    整数测试:A, B
        A -gt B: 大于
        A -ge B: 大于等于
        A -eq B: 等于
        A -lt B: 小于
        A -le B: 小于等于
        A -ne B: 不等于
       
        例:
       
    字符串测试:A, B
        A > B
        A < B
        A >= B
        A <= B
        A == B或A = B: 等值比较
        A != B: 不等于
        -z A: 判断A是否为空,空则为真,不空为假
        -n A: 判断A是否不空,不空为真,空为假
       
    条件取反:
        ! CONDITION
   
    条件测试语法:
        单分支:
            if CONDITION; then
                CMD1
                CMD2
            fi
           
            例:传递一个参数给test.sh,判断是否为偶数,是则打印,否则不打印
                test.sh 5
               
                #!/bin/bash
                shuzi=$1
                if [ $[$shuzi%2] -eq 0 ];then
                    echo $shuzi
                fi
               
                条件表达式为双中括号[[ $shuzi%2 -eq 0 ]]也可以
                bash -n test.sh
                    检查脚本有无语法错误
                bash -x test.sh 10
                    调试执行,一步一步执行,打印执行步骤,最后打印执行结果
                   
            例:传递一个参数给脚本,而后以此参数为用户名,添加此用户
                useradd.sh
                #!/bin/bash
                username=$1                       
                if ! id $username ;then
                    useradd $username
                fi
               
                执行bash -n useradd.sh检查脚本是否存在语法错误
                bash -x useradd.sh aaa
                    打印执行过程,最终打印执行结果
   
        if可以嵌套:
            if CONDITION; then
                if CONDITION2; then
                    CMD
                fi
            fi
           
        条件取反:
            ! COMMAND
           
        双分支:
            if CONDITION; then
                分支1
            else
                分支2
            fi
           
            练习2:
                传递两个整数给脚本,返回其较大者
               
                test.sh
                #!/bin/bash
                if $1 -gt $2;then
                    echo $1
                else
                    echo $2
                fi
               
                bash -n
       
            练习3:写一个脚本
                1)传递一个参数给脚本,此参数为用户名
                2)如果用户存在的话,则执行如下任务
                    a)如果用户的id号小于500,显示其为管理员或系统用户
                    b)否则,显示为普通用户
                3)如果用户不存在,则添加
               
                #!/bin/bash
                if id $1 &> /dev/null;then
                    userid=`id -u $1`
                    if [ $userid -lt 500 ];then
                        echo "$1 is sysadmin or sysuser."
                    else
                        echo "$1 is a common user"
                    fi
                else
                    useradd $1
                    if [ $? -eq 0 ];then
                        echo "Add user $1"
                    else
                        echo "Fail to add $1"
                    fi
                fi
               

                &<:标准输出和错误输出都输出进黑洞/dev/null
                useradd命令是管理员才能使用的命令,所以有可能执行失败,故用判断$?
               
        多分支的if语句:
            if CONDITION1-TRUE;then
                分支1
            elif CONDITION2-TRUE;then
                分支2
            elif CONDITION3-TRUE;then
                分支3
            ...
            else
                分支n
            fi
           
            例:
            练习1:传递一个参数给脚本
                如果参数为quit,则显示说要退出脚本;
                如果参数为yes,则显示说继续;
                否则,则显示为无法识别;
                test.sh
                #!/bin/bash
                if [ $1 == "quit" ];then
                    exit
                elif [ $1 == "yes" ];then
                    echo "continue"
                else
                    echo "not find age"
                fi
       
            练习2:传递一个用户名参数给脚本
                (1) 如果用户的id号为0,则显示为管理员;
                (2) 如果用户的id号大于6000,则显示为guest;
                (3) 如果用户的id号大于500,则显示为普通用户;
                (4) 如果用户的id号大于0, 则显示为系统用户;
                (5) 否则,无法识别;
               
               
            练习3:写一个脚本;
                (1) 传递一个磁盘设备文件给脚本;
                (2) 判断此设备是否存在;如果存在,则清除此设备上的所有分区;
                (3) 否则,则无此设备;
       
    COMMAND用作条件:
        (1) 使用命令执行结果;
            (a) 使用命令引用 ``
            (b) 使用比较操作符

            例:[ `id -u $username` -lt 500 ]
                userid=`id -u $username`
                [ $userid -lt 500 ]

        (2) 使用命令的退出状态码
            (a) 先运行命令
            (b) 退出状态码

            引用方式两种:
                (a) if COMMAND; then
                    注意:COMMAND不能被命令引用;COMMAND的执行结果通常没有意义,所以其结果通常(&>)被定向至/dev/null
                (b) 先执行命令,后判断退出状态码是否为0
                    COMMAND
                    if [ $? -eq 0 ]
           
条件测试:
    文件u测试:$file
        -e $file:是否存在,存在则为真 [ -e /tmp/aaa ]
        -a $file:同上,弃用
        -f $file:文件是否存在,且为普通文件
        -d $file:是否存在且为目录
        -h $file:是否存在且为符号链接文件
        -L $file:同上
        -b $file:是否存在且为块设备文件
        -c $file:是否存在且为字符设备文件
        -S $file:是否存在且为套接字文件
        -p $file:是否存在且为管道文件
       
        -r $file:当前用户对此文件是否拥有读权限
        -w $file:                          写权限
        -x $file:                          执行权限
       
        -u $file:文件是否拥有suid权限
        -g $file:文件是否拥有sgid权限
        -k $file:文件是否拥有sticky权限
       
        -O $file:当前用户是否为文件的属主
        -G $file:当前用户是否属于文件的属组
       
        -N $file:文件自从上一次被读取之后,是否被修改过
       
        $f1 -nt $f2:文件f1是否比文件f2新
        $f1 -ot $f2:文件f1是否比文件f2旧
        $f1 -ef $f2:f1和f2是否为同一个文件的硬链接
           
        练习:写一个脚本,传递一个文件路径参数给脚本
        (1) 存在,则显示有此文件;
        (2) 否则,则显示无此文件

    练习:写一个脚本,传递一个文件路径参数给脚本
        (1) 如果脚本无参数,则显示必须给至少一个参数,退出脚本;退出码5;
        (2) 路径指向的文件如果不存在,则直接退出脚本;退出码为6;
        (3) 判断文件类型:
            (a) 如果是普通文件,则显示为"common file";
            (b) 如果是目录,则显示为"directory";
            (c) 如果是符号链接,则显示为"symbolic link file";
            (d) 如果是块设备,则显示为“block device file";
            (e) 如果是字符设备,则显示为"character device file";
            (f) 否则,则显示为“unkown”;   
           
        #!/bin/bash
        if [ $# -lt 1 ];then
            echo "At least one argument"
            exit 5
        fi
       
        if [ ! -e $1 ];then
            echo "No such file"
            exit 6
        fi
       
        if [ -f $1 ];then
            echo "common file"
        elif [ -d $1 ];then
            echo "directory"
        elif [ -L $1 ];then
            echo "Symbolic file"
        elif [ -b $1 ];then
            echo "block device"
        elif [ -c $1 ];then
            echo "character device"
        else
            echo "unknown type."   
        fi
       
        $#是脚本传递的参数个数
       
    练习:写一个脚本,其使用格式如下所示(其中所有的script.sh均为用户给定的脚本名称,其要跟随脚本名称变化):
        script.sh {start|stop|restart|status}
        (1) 调用时至少传递一个参数;否则,则显示帮助信息,并退出脚本;
        (2) 如果参数为“start”, 则创建空文件/var/lock/subsys/script.sh,并显示“starting script.sh successfully.”;
        (3) 如果参数为“stop”,则删除空文件/var/lock/subsys/script.sh,并显示“stopping script.sh successfully.”;
        (4) 如果参数为“restart”,则删除空文件/var/lock/subsys/script.sh,并显示“stopping script.sh successfully.”;而后重新创建之,并显示“restarting script.sh successfully.”;
        (5) 如果参数为“status”,则
            (a) 如果文件/var/lock/subsys/script.sh文件存在,则显示“running”;
            (b) 否则,则显示为"stopped"
        (6) 其它任意参数,均显示帮助信息后退出;帮助信息格式为命令使用格式;
        
            #!/bin/bash
            #
            # chkconfig: 2345 95 5
            # description: test service script
            #
            prog=`basename $0`
            lockfile=/var/lock/subsys/$prog

            if [ $# -lt 1 ]; then
                echo "Usage: $prog {start|stop|restart|status}"
                exit 1
            fi

            if [ "$1" == 'start' ]; then
                if [ -e $lockfile ]; then
                    echo "$prog is aleady running."
                    exit 1
                else
                    touch $lockfile
                    echo "Starting $prog succefully."
                fi
            elif [ "$1" == 'stop' ]; then
                if [ -e $lockfile ]; then
                    rm -f $lockfile
                    echo "Stopping $prog succefully."
                else
                    echo "$prog is not running."
                    exit 1
                fi
            elif [ "$1" == 'restart' ]; then
                if [ -e $lockfile ]; then
                    rm -f $lockfile
                    echo "Stopping $prog succefully."
                    touch $lockfile
                    echo "Starting $prog succefully."
                else
                    touch $lockfile
                    echo "Starting $prog succefully."
                fi
            elif [ "$1" == 'status' ];then
                if [ -e $lockfile ];then
                    echo "$prog is running."
                else   
                    echo "$prog is stopped."
                fi
            else
                echo "Usage: $prog {start|restart|status|stop}"
                exit 1
            fi
       
       
    组合测试条件:
        给条件添加逻辑操作符:
            或:-o: [ -z "$hostname" -o "$hostname" == 'localhost' ]
                -z "$hostname": 判断字符串是否为空
               
            与:-a: [ $uid -gt 0 -a $uid -lt 500 ]
            非:[ ! EXPRESSION ]
           
            练习:写一个脚本,取得当前的主机名,判断
                (1) 如果主机名为空或为"localhost",则将其命名为stuX.lianshu.com;
                (2) 否则,则显示主机名即可;
                #!/bin/bash
                hostname=`hostname`
                if [ -z "$hostname" -o "$hostname" == "localhost"];then
                    hostname stuX.lianshu.com
                    #echo "stuX.lianshu.com" > /proc/sys/kernel/hostname
                else
                    echo "The hostname is: $hostname"
                fi
       
        练习2:写一个脚本,传递一个参数给脚本;此参数为用户名
            (1) 如果用户不存在,则直接退出脚本;
            (2) 如果用户存在,
                id=0,则显示为“system admin”
                0<id<500,则显示为“system user”
                id>=500,则显示为“Common user.”
                    #!/bin/bash
                    #
                    if ! id $1 &> /dev/null; then
                        echo "No such user."
                        exit 1
                    fi

                    uid=$(id -u $1)

                    if [ $uid -eq 0 ]; then
                        echo "Sys Admin."
                    elif [ $uid -gt 0 -a $uid -lt 500 ];then
                        echo "Sys User."
                    else
                        echo "Common User."
                    fi

        练习3:写一个脚本,传递一个参数给脚本;此参数为用户名
            (1) 如果用户不存在,则直接退出脚本;
            (2) 如果用户的id号大于等于500,且其shell为“以sh结尾的”类型,则显示“a user can log system.”;否则,显示用户无法登录;
                #!/bin/bash
                #
                if ! id $1 &> /dev/null; then
                    echo "No such user."
                    exit 1
                fi

                if [[ `id -u $1` -ge 500 ]] && [[ `grep "^$1\>" /etc/passwd | cut -d: -f7` =~ /bin/.*sh$ ]]; then
                    echo "a user can log system."
                else
                    echo "a user cannot log."
                fi
           
                ^$1\>: (^root\>)以root开头,且词尾锚定,排除包含root字符的,例如rootab
                =~为模式匹配
   
    组合测试条件:短路操作符
        与:COMMAND1 && COMMAND2
            COMMAND1的退出转态结果为假,则COMMAND2不用运行,则有最终结果
        或:COMMAND1 || COMMAND2
            COMMAND1的退出转态结果为真,则COMMAND2不用运行,则有最终结果
        非:! COMMAND
       
        例:[ ! -d /tmp/test ] && mkdir /tmp/test
            [ -d /tmp/test ] || mkdir /tmp/test
           
        练习4:写一个脚本,完成如下任务:
            (1) 如果httpd进程或nginx进程处于运行中,则显示“web server started.”,并显示其监听的端口;
            (2) 否则显示“no web server.”;
           
                if pidof httpd &> /dev/null || pidof nginx &> /dev/null;then
                    echo "web server started."
                else
                    echo "no web server."
           
    交互式脚本:
        read [OPTIONS] [name ...]
            -p "PROMPT": 输入过程中,想删除,则必须按ctrl+delete,单独的delete键是执行不了删除操作的
                read -p "pls input:" aa
                   
            -t #: 超时时间
                read -p "pls input:" -t 2 aa
       
        给变量以默认值:
            [ -z "$VAR" ] && VAR=VALUE
       
        练习1:显示如下菜单给用户
            cpu) show cpu infomation;
            mem) show memory infomation;
            disk) show disk infomation;
            *) quit
            提示用户键入选项:
            (1) cpu: 显示CPU相关的信息
            (2) mem: 显示内存相关的信息
            (3) disk: 列出磁盘设备
            (4) 其它任何信息,即为退出脚本
           
            #!/bin/bash
            #
            cat << EOF
                        cpu) show cpu infomation;
                        mem) show memory infomation;
                        disk) show disk infomation;
                        *) quit
            =================================================================
            EOF
            read -p "Your  choice: " choice

            if [[ "$choice" == 'cpu' ]]; then
                lscpu
            elif [[ "$choice" == 'mem' ]]; then
                free -m
            elif [[ "$choice" == 'disk' ]]; then
                fdisk -l /dev/sd[a-z]
            else
                echo "quit"
                exit 0
            fi
           
    case语句:
        简洁版的多分支if语句
       
        语法格式:
            case 变量引用  in
            PATTERN1)
                分支1
                ;;
            PATTERN2)
                分支2
                ;;
            ...
            *)
                分支n
                ;;
            esac
           
            PATTERN可使用通配符:
                *:任意长度的任意字符
                ?: 任意单个字符
                []:指定范围内的任意单个字符
                a|b: a或者b
           
        练习1:写一个脚本,使用tar工具把/etc目录备份至/backup目录中,名字为/backup/etc-日期时间.tar.{xz|bz2|gz};
            (1) 显示如下菜单
                xz) xz compress tool
                gzip) gzip compress tool
                bzip2) bzip2 compress tool
                *) wrong choice and quit
            (2) 根据用户选择的工具,执行相应操作;如果用户没有键入任何数据,则默认使用xz;

            #!/bin/bash
            cat<<EOF
                    xz)xz compress tool
                    gzip)gzip compress tool
                    bzip2)bzip2 compress tool
                    *)wrong choice and quit
            =======================================================
            EOF
            read -t 5 -p "pls input the choice:" command
            [ -z $command ] && command="xz"
             ! [  -d /backup ] ||  mkdir /backup

            file_path=/backup/etc"-$(date +%Y%m%d%H%M).tar"
            echo $file_path
            case $command in
                "xz")
                        echo "xz"
                        #tar -Jcf  $file_path.xz /etc/*
                        ;;
                "gzip")
                        echo "gzip"
                        #tar -zcf  $file_path.gz /etc/*
                        ;;
                "bzip2")
                        echo "bzip2"
                        #tar -jcf  $file_path.bzip2 /etc/*
                        ;;
                *)
                        echo "wrong choice"
                        ;;
            esac   

posted @ 2015-10-20 14:53  lucky_zhang  阅读(4730)  评论(0编辑  收藏  举报