zoukankan      html  css  js  c++  java
  • shell中的条件判断

    1.测试内容 

    2.测试方法 

    3.应用示例

      在shell脚本中应用条件测试时,关键是“测试表达式”。在条件语句中测试时首先分清楚测试什么类型的信息:数字、字符串、还是一个文件,要么就是一个逻辑关系。当遇到不同的测试类型时自然就有不同的“测试属性”,理解这个测试属性是必须的。不然就不知道从何处下手。

      判断的返回值:真、假。

      当判断的条件是一个命令时,始终认为是返回为真;缺省表达式,返回为假。

    命令用法
    test test EXPRESSION
    [ [ EXPRESSION ]

    例子:缺省表达式,默认为“假”

    [view@payqa2 ~]$ [ ] && echo "true"
    [view@payqa2 ~]$ [ ! ] && echo "true"
    true

    1.测试内容


      表达式的“测试属性”分类

        1.1.字符串测试

        1.2.数字比较

        1.3.文件测试

        1.4.逻辑判断

     

     

    1.1.字符串测试(判断字符串相等、为空、不为空)

      使用时,与表达式左右要有一个空格分开。

    表达式用法

    test[ 
    test $lastuser [ $loguser ]          ①
    为空
    test $lastuser == $loguser
    [ $loguser == "sunny" ]   
    相等
    test -n lastuser [ -n $lastuser ]       非空
    test -z loguser [ -z $loguser ]       为空
    比较时“==”两边保留空格,赋值时取消空格。
     

     

    1.1.1.测试为空、不为空时,条件判断执行的语句

    $ cat string_is_null.sh
    #!/bin/bash
    #
    if [ $1 ]
    then
            echo 'Execute then. true'
    else
            echo 'Execute else. false'
    fi

      为空时,执行了else语句;不为空,执行了then语句。

    $ ./string_is_null.sh
    Execute else. false
    $ ./string_is_null.sh  hello
    Execute then. true

    1.1.2.“-n”如何影响if选择语句

    $ cat string_n.sh
    #!/bin/bash
    #
    judge(){
            if [ -n $1 ]
            then
                    echo 'Execute then. true'
            else
                    echo 'Execute else. false'
            fi
    }
    K="hello"
    S=""
    
    echo -ne 'K="hello",	[ -n $K]	'
    judge $K
    echo -ne 'S="",		[ -n $S]	'
    judge $S
    $ ./string_n.sh
    K="hello",      [ -n $K]        Execute then. true
    S="",           [ -n $S]        Execute then. true

      测试结果,令人吃惊!

     

    1.1.3.把上边“-n”替换成“-z”

    $ ./string_z.sh
    K="hello",[ -z $K]    Execute else. false
    S="",[ -z $S]         Execute then. true

      为空时,执行了then语句;不为空,执行了else语句。

     

    1.1.4.测试位置变量的有无

    存在位置变量的时候,不提示;不存在位置变量时,提示未知变量为空。

    # cat test.sh
    #!/bin/bash
    #
    if [ -z $1 ];then
            echo '$1 is null.'
    fi
    # ./test.sh 7
    # ./test.sh hello
    # ./test.sh
    $1 is null.

    也可以通过这个小程序来测试脚本里使用了某个环境变量(ZCW_TS)是否存在。

     

    1.1.5.比较时竟然可以用“=”

      阅读tomcat脚本时发现的(setclasspath.sh)

    [root@iZm5e7mrdpxqswsmtrugo6Z tmp]# cat haha.sh 
    #!/bin/bash
    
    if [ "x${hh}" = "x" ]; then
        echo "My god, = is ok."
    else
        echo "he he."
    fi
    [root@iZm5e7mrdpxqswsmtrugo6Z tmp]# ./haha.sh 
    My god, = is ok.

     1.1.6.错误

      这段代码是有问题的,运行后会懵……

    if [ '-t'='$1' ]; then
            echo "ceshi: -t."
    fi
    
    if [ "-f"==$1 ]; then
            echo "ceshi: -f."
    fi

     效果如下:

    [root@file work]# ./test_para.sh -f
    ceshi: -t.
    ceshi: -f.

    从运行效果看,两个 if 语句都成功匹配了。正确的结果应该是不匹配的。问题就出在“=”两边没有使用空格空开。

    1.2.数字比较(整数比较大小、等于)

    表达式用法

    exprtest[说明

    $age1 -eq $age2

    $age1 -ne $age2

    test $age1 -eq $age2

    test $age1 -ne $age2

    [ $age1 -eq $age2 ]

    [ $age1 -ne $age2 ]

    等于

    不等于

    $age1 -gt $age2

    $age1 -lt $age2

    test $age1 -gt $age1

    test $age2 -lt $age2

    [ $age1 -gt $age1 ]

    [ $age2 -lt $age2 ]

    大于

    小于

    $age1 -ge $age1

    $age2 -le $age2

    test $age1 -ge $age1

    test $age2 -le $age2

    [ $age1 -ge $age1 ]

    [ $age2 -le $age2 ]

    大等于

    小等于

     

    *举例说明

    $int1 -eq $int2: # 数字相等
    $int1 -ge $int2: # int1 ≥ int2
    $int1 -gt $int2: # 〉
    $int1 -le $int2: # ≤
    $int1 -lt $int2: # 〈
    $int1 -ne $int2: # ≠

     

      例子:当k的值大于3时,循环结束。

    #!/bin/bash
    declare -i k=0
    
    while true; do
        if [ $k -gt 3 ]; then
            exit;
        else
            let k+=1
        fi
        echo $k
    done

      例子:比较返回值

    check_it () {
            if [ "true" == $1 ]
            then
                    return 0
            else
                    return 1
            fi  
    }
    
    
    if [[ 1 != $(check_it "true") ]]#可以带双引号,也可以不带,1都可以正确识别;
    then
            echo "false"
    fi

    1.3.文件测试

    表达式用法

    test[说明
    -b /dev/cdrom [ -b /dev/cdrom ] 存在且为块文件
    -c /etc/inittab
    [ -c /etc/fstab ] 存在……字符文件
    -d /data01
    …… ……且为目录文件
    -e /~/.ssh/keys
    …… ……存在
    -s /~/.ssh/keys …… 是否非空
    -f /etc/http/conf.d/ssl.cf
    …… 存在且为常规文件
    -w /data01/tmp/http.log
    …… ……可写
    -L /data01/tmp/http.log
    …… ……符号链接
    -u /data01/tmp/http.log
    …… 设置suid位
    -r /data01/tmp/http.log …… 存在且可读
    -x /dinglicom/bin/httpd
    …… ……可执行

     

    *说明

    file1 -nt file2:文件 file1 更新一些

    file1 -ot file2:旧

     

    -d filefile文件存在,并且是一个目录

    -e file文件存在

    -h file文件存在,并且是一个符号链接

    -L file:“同上”

    -r file文件存在,并且被赋予了“读”权限

    -w file文件存在,并且被赋予了“写”权限

    -x file:文件存在,并且被赋予了“执行”(“进入目录”)权限

    -s file文件存在,并且大小大于零

    -S file文件存在,并且是一个套接字文件

     

    [web@h p]$ test -x dir_perm_test/
    [web@h p]$ echo $?
    1
    [web@h p]$ ll dir_perm_test/
    total 20
    drw------- 2 web web 4096 Apr  8 01:44 dir_perm_test
    [web@h p]$ ll dir_perm_test/
    ls: cannot access dir_perm_test/file1: Permission denied
    ls: cannot access dir_perm_test/file4: Permission denied
    ls: cannot access dir_perm_test/file2: Permission denied
    ls: cannot access dir_perm_test/file3: Permission denied
    total 0
    -????????? ? ? ? ?            ? file1
    -????????? ? ? ? ?            ? file2
    -????????? ? ? ? ?            ? file3
    -????????? ? ? ? ?            ? file4
    [web@h p]$ cd dir_perm_test/
    -bash: cd: dir_perm_test/: Permission denied
    [web@h p]$ chmod u+x dir_perm_test/;cd dir_perm_test/
    [web@h p]$ touch file5
    [web@h p]$ test -s file5
    [web@h p]$ echo $?
    1

     

    1.4.逻辑判断组合

      “逻辑判断组合”就像胶水一样把上边“3类”逻辑判断结合起来。

    表达式用法

     

    符号含义
    !
    -a
    -o

      逻辑判断在脚本中的应用:

    •  错误示范(组合字符串判断):

    #!/bin/bash
    #
    clear
    #
    DISPLAY="Usage show.
    
    d/D show disks usages.
    
    m/M show memory usages.
    
    s/S show swap usages.
    
    
    By the way, if you want exit this script, input 'quit' or 'q'.
    "
    CHOICE=""
    #
    echo -e $DISPLAY
    read -p "Your choice: " CHOICE
    #
    #while [ $CHOICE != "quit" ]
    while [ $CHOICE != "quit" -o $CHOICE != "q" ]
    do
        # test
        #echo $CHOICE
        # while 1
        case $CHOICE in
        d|D)
            echo "Disk info:"
            df -Ph
            ;;
        m|M)
            echo "Memory info:"
            free -m | grep -v "swap"
            ;;
        s|S)
            echo "Swap info:"
            free -m | grep -i "swap"
            ;;
        *)
            echo -e "	Unkown optios."
            sleep 1
            echo -e $DISPLAY
        esac
        
        # while 2
        read -p "Once more. Your choice: " CHOICE
        # test
        #echo $CHOICE
    
    done

      脚本执行后无法退出,错误就出在逻辑判断上。

    •  正确示范:

    while [ $CHOICE != "quit" -a $CHOICE != "q" ]

      条件判断由于使用了逻辑组合“-o”、“-a”,分别需要对于前后两个逻辑判断计算结果。需要退出时,必须判断为假。当使用了组合时,会综合判断。

      因为,“或”在满足后边逻辑判断为“假”需要退出时,前边判断为真,后边判断失效,整体结果为真,程序继续执行;反之,前边逻辑判断满足退出条件时,为假,会继续执行后边逻辑判断为“真”的条件测试(前边为假的“或”运算,后边判断不失效),整体结果依然为真;于是,循环体无法退出。

      当选择“与”时,任意一个退出满足条件满足了即退出循环体。若前边判断为“假”,后边失效,整体结果为“假”,循环终止;当前边为“真”时,后边判断继续,进行为“假”的判断,整体结果为假

    *说明

    缺省表达式,返回为假。

    [web@h p]$ test
    [web@h p]$ echo $?
    1
    [web@h p]$ test da
    [web@h p]$ echo $?
    0
    
    [web@h p]$ [ -d $LOCALDIRECTORY ] && $RM -fr $LOCALDIRECTORY
    [web@h p]$ [ ! -d $LOCALDIRECTORY ] && $MKDIR -pv $LOCALDIRECTORY

    --------------------------

      小括号($(cat /etc/inittab))用来运行命令中括号([ i -eq j ])用来做条件判断大括号(${user}1)用来界变量定字符串长度。两个小括号套用,在 for循环 里使用、或者 数字运算

    --------------------------

    2.测试方法


      测试文件属性、测试字符串、数字比较。

    用法说明
    -a file 文件存在为真
    -b file 是块文件为真
    -c file 是字符文件为真
    -d file 是目录为真
    -e file 文件存在为真
    -f file 是常规文件为真
    -g file 文件存在,且set-group-id为真
    -h file 文件为符号链接为真
    -k file  
    -p file  
    -r file 可读文件为真
    -s file 文件大于0为真
    -S file 是套接字文件为真
    -t fd  

    -u file

     
    -w file 文件可写为真
    -x file 文件可执行为真
    -G file  
    -L file 文件为符号链接为真
    -N file 最后一次被读取之后修改为真
    -O file  
    file1 -ef file2

    硬链接文件为真

    设备号一致、节点号一致

    file1 -nt file2

    file1的“修改时间”更新为真

    file1存在,file2不存在为真

    file1 -ot file2

    file1的“修改时间”更旧为真

    file1不存在,file2存在为真
    -o optname  
    -v varname  
    -z string 字符串长度为零时为真

    string

    -n string

    字符串长度非零时为真

    string1 = string2

    字符串相等时为真
    string1 != string2 字符串不相等时为真
    string1 < string2 strring1排序在前时为真
    string1 > string2  
    int1 -eq int2 数字相等
    int1 -ge int2 大于等于
    int1 -gt int2 大于
    int1 -le int2 小于等于
    int1 -lt int2 小于
    int1 -ne int2 数字不等
    EXPR1 -a EXPR2 与关系
    EXPR1 -o EXPR2 或关系
    ! EXPR 取反

     

     2.应用示例


      例子:字符串长度“非零”为真

    [view@payqa2 ~]$ string=""
    [view@payqa2 ~]$ [ $string ] && echo "true"
    [view@payqa2 ~]$ string="hello"
    [view@payqa2 ~]$ [ $string ] && echo "true"
    true

       移动文件 在 Shell 脚本中处理通配符,比较时 = 两边需要有空格,判断位置参数存在与否,逻辑判断作为条件判断,屏蔽命令输出。

     1 # variables
     2 DESTDIR=/ftp/school/teacher
     3 SOURDIR=/view
     4 USERNAME=develop
     5 GROUPNAME=develop
     6 
     7 if [ ! -z $1 ]; then
     8         # list file in destation directory.
     9         if [ -f = $1 ]; then
    10                 ls -l $DESTDIR
    11 
    12                 exit 1
    13         fi
    14 
    15         # clear files in destation directory.
    16         if [ --clear = $1 ]; then
    17                 env rm -fr ${DESTDIR}/*
    18 
    19                 exit 2
    20         fi
    21 
    22         # test zip file ok.
    23         if [ -t = $1 ]; then
    24                 for tf in $(ls -1 $DESTDIR); do
    25                         env file ${DESTDIR}/${tf} | grep -F "Zip archive data" &>/dev/null && zip -T ${DESTDIR}/$tf
    26                 done
    27 
    28                 exit 3
    29         fi
    30 else
    31         # Move to destation directory.
    32         ls -1 ${SOURDIR}/* 2>/dev/null && env mv -v -t $DESTDIR ${SOURDIR}/* && chown -R $USERNAME:$GROUPNAME $DESTDIR
    33         exit 0
    34 fi
    View Code
    一切代码都是为了生活,一切生活都是调剂
  • 相关阅读:
    mustache.js 使用
    iscroll4 input textarea不能获得焦点问题
    object-fit?
    window.open()被拦截问题
    JSONP
    mouseenter和mouseover的区别
    前端页面卡顿-代码优化
    如何设置html中img宽高相同-css
    iscroll使用之页面卡顿问题
    iScroll的简单使用
  • 原文地址:https://www.cnblogs.com/argor/p/7909171.html
Copyright © 2011-2022 走看看