• 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   

  • 相关阅读:
    语言相关
    一道简单DP题
    一道概率题
    Android CrashHandler
    一道简单数学题
    面试中遇到的随机题目
    VMWare 无损扩展磁盘大小
    Android 源码编译记录
    Android handler 内存泄露分析及解决方法
    Android 反编译
  • 原文地址:https://www.cnblogs.com/yajing-zh/p/4894835.html
Copyright © 2020-2023  润新知