• shell脚本编程测试类型上


    一bash的条件测试

    判断某需求是否满足,需要由测试机制来实现。专用的测试表达式需要由测试命令辅助完成测试过程。


    评估布尔声明,以便用在条件性执行中。若真,则返回0;若假,则返回1。


    测试命令:
    • test EXPRESSION
    • [ EXPRESSION ]
    • [[ EXPRESSION ]]和上面两个不同的在于支持正则表达式
    注意:EXPRESSION前后必须有空白字符

    (一)使用test命令

    [root@centos7 ~]# type test
    test is a shell builtin
    [root@centos7 ~]# type [
    [ is a shell builtin 内部命令
    [root@centos7 ~]# type [[
    [[ is a shell keyword

    比较两个字符串是否相同

    [root@centos7 ~]# srtr1=abc
    [root@centos7 ~]# srtr2=abc
    [root@centos7 ~]# test str1=str2
    [root@centos7 ~]# echo $?
    0
    [root@centos7 ~]# test str1 = str2
    [root@centos7 ~]# echo $?
    1
    [root@centos7 ~]# srtr1=abc
    [root@centos7 ~]# srtr2=def
    [root@centos7 ~]# test str1 = str2
    [root@centos7 ~]# echo $?
    1


    [root@centos7 ~]# test str1 != str2
    [root@centos7 ~]# echo $?
    0
    [root@centos7 ~]# test str1 ! = str2 
    #注意!=一定要连在一起的 -bash: test: too many argumentsy

    (二)使用中括号[ ]

    系统里面的脚本也是使用中括号。

    使用中括号会更好,因为test是字符串,容易和其他的字符串混在一起,而中括号一目了然。

    注意使用中括号EXPRESSION前后必须有空白字符

    [root@centos7 ~]# srtr1=abc
    [root@centos7 ~]# srtr2=abc
    [root@centos7 ~]# [test1 = test2]
    -bash: [test1: command not found 
    #使用中括号EXPRESSION前后必须有空白字符 [root@centos7 ~]# [ test1 = test2 ] [root@centos7 ~]# echo $? 0

     系统里面的脚本也是使用中括号

    [root@centos73 shell_scripts]# cat  /etc/init.d/functions  
    # -*-Shell-script-*-
    #
    # functions This file contains functions to be used by most or all
    #       shell scripts in the /etc/init.d directory.
    #
    
    TEXTDOMAIN=initscripts
    
    # Make sure umask is sane
    umask 022
    
    # Set up a default search path.
    PATH="/sbin:/usr/sbin:/bin:/usr/bin"
    export PATH
    
    if [ $PPID -ne 1 -a -z "$SYSTEMCTL_SKIP_REDIRECT" ] && 
            [ -d /run/systemd/system ] ; then
        case "$0" in
        /etc/init.d/*|/etc/rc.d/init.d/*)
            _use_systemctl=1
            ;;
        esac
    fi

    在中括号里面,只要中括号里面有东西就是为真,没有就是为假

    [root@centos7 ~]# [ ] && echo true ||  echo false 
    false
    [root@centos7 ~]# [ 123 ] && echo true ||  echo false 
    true
    [root@centos7 ~]# [ 1243] && echo true ||  echo false 
    -bash: [: missing `]'
    false
    [root@centos7 ~]# [1243] && echo true ||  echo false 
    -bash: [1243]: command not found
    false
    [root@centos7 ~]# [1243 ] && echo true ||  echo false 
    -bash: [1243: command not found
    false

     ?如果中括号里面是引号,就要空格

    [root@centos7 ~]# [ "" ] && echo true ||  echo false 
    false
    [root@centos7 ~]# [ " " ] && echo true ||  echo false 
    true

    如果变量是有值,但是是空字符串,那么直接写就假,要使用引号引起来

    [root@centos7 ~]# a=36
    [root@centos7 ~]# [ $a ] && echo true ||  echo false 
    true
    [root@centos7 ~]# unset a
    [root@centos7 ~]# a=" "
    [root@centos7 ~]# [ $a ] && echo true ||  echo false 
    false
    [root@centos7 ~]# [ "$a" ] && echo true ||  echo false 
    true

    可以使用中括号判断某个变量是否赋值了

    [root@centos7 ~]# [ "x"$a = "x" ] && echo true ||  echo false 
    #这个x纯粹就是为了组合的,x和字符串组合,如果a没有定义,那么x就等于x。这里的x是一个字母代表,使用其他的字母也可以。 true [root@centos7 ~]# a=245 [root@centos7 ~]# [ "x"$a = "x" ] && echo true || echo false false

    在6里面的vim /etc/rc.sysinit中使用的就是这种方法。

    645 # Start up swapping.
    646 update_boot_stage RCswap
    647 action $"Enabling /etc/fstab swaps: " swapon -a -e
    648 if [ "$AUTOSWAP" = "yes" ]; then
    649         curswap=$(awk '/^/dev/ { print $1 }' /proc/swaps | while read x; do get_numeric_dev dec $x ; echo -n " "; done)
    650         swappartitions=$(blkid -t TYPE=swap -o device)
    651         if [ x"$swappartitions" != x ]; then
    652                 for partition in $swappartitions ; do
    653                         [ ! -e $partition ] && continue
    654                         majmin=$(get_numeric_dev dec $partition)
    655                         echo $curswap | grep -qw "$majmin" || action $"Enabling local swap partitions: " swapon $partition
                                                                                                                                      

    二bash的字符串测试

    字符串测试操作符的作用包括:比较两个字符串是否相同、测试字符串的长度是否为零、字符串是否为NULL等。

    (一)常用字符串测试操作符及其说明:


    == 是否等于


    > ascii码是否大于ascii码


    < 是否小于


    != 是否不等于


    =~ 左侧字符串是否能够被右侧的PATTERN所匹配,注意: 此表达式一般用于[[ ]]中;扩展的正则表达式

    -z "STRING“ 字符串是否为空,空为真,不空为假。若字符串的长度为0,则为真,即测试表达式成立, z可以理解为zero的缩写"


    -n "STRING“ 字符串是否不空,不空为真,空为假。若字符串的长度不为0,则为真,即测试表达式成立, n可以理解为no zero


    注意:用于字符串比较时的用到的操作数都应该使用引号

     
    "串1"="串2"   若字符串1等于字符串2,则为真,即测试表达式成立,可使用"==”代替

    "串1"!="串2" 若字符串1不等于字符串2,则为真,即测试表达式成立,但不能用"!==”代替"!


    (二)字符串测试操作符的注意事项:


    对于字符串的测试,一定要将字符串加双引号之后再进行比较。

    如[-n  "$var"] ,特别是使用中括号[ ]的场景。

    比较符号(例如=和!-)的两端一定要有空格。
     
    "!=”和“=”可用于比较两个字符串是否相同。

     注意一般相等或者不等写上一个中括号就可以

    [root@centos7 ~]# var=abc;[ "$var" != "abc" ]  &&  echo true ||  echo false
    false
    [root@centos7 ~]# var=abc;[ "$var" = "abc" ]  &&  echo true ||  echo false
    true

    两个中括号

    [root@centos7 ~]# var=abc;[[ "$var" = "abc" ]]  &&  echo true ||  echo false
    true
    [root@centos7 ~]# var=abc;[[ "$var" != "abc" ]]  &&  echo true ||  echo false
    false

    两个中括号的优点就是支持正则表达式

    =~ 左侧字符串是否能够被右侧的PATTERN所匹配
    注意: 此表达式一般用于[[ ]]中;扩展的正则表达式

    [root@centos7 ~]# var=abcd;[[ "$var" =~ cd ]]   &&  echo true || echo false
    true
    #只要变量包含了字符串,返回的值就是真
    
    [root@centos7 ~]# var=abc;[[ "$var" =~ cd ]]   &&  echo true || echo false
    false
    [root@centos7 ~]# var=abc;[[ "$var" =~ ab?  ]]   &&  echo true || echo false
    true
    [root@centos7 ~]# var=b;[[ "$var" =~ a?  ]]   &&  echo true || echo false
    true
    [root@centos7 ~]# var=b;[[ "$var" =~ b+  ]]   &&  echo true || echo false
    true
    [root@centos7 ~]# var=a;[[ "$var" =~ .  ]]   &&  echo true || echo false
    true
    [root@centos7 ~]# var=a;[[ "$var" =~ ..  ]]   &&  echo true || echo false
    false
    [root@centos7 ~]# var=a;[[ "$var" =~ .  ]]   &&  echo true || echo false 
    #点表示的是包含任意1个字符 true

    [root@centos7 ~]# var=a;[[ "$var" =~ .. ]] && echo true || echo false
    #点表示的是包含任意1个字符,而2个点表示的是包含任意2个字符,而变量的值只有1个字符,所以返回的是假。 false [root@centos7 ~]# var=abc;[[ "$var" =~ .. ]] && echo true || echo false
    #点表示的是包含任意1个字符,而2个点表示的是包含任意2个字符,而变量的值是3个字符,所以返回的是真 true [root@centos7 ~]# var=abc;[[ "$var" =~ ^..$ ]] && echo true || echo false
    #已经锚定了任意2个字符,而变量的值是3个字符,所以返回的是假 false

    判断文件名的后缀是否是sh的

    正则表达式很绕,要多看

    [root@centos7 ~]# filename=f1.sh;  [[ "$filename"  =~  .*.sh$ ]]   && echo true  ||  echo  false    
    true
    [root@centos7 ~]# filename=f1.shshsh;  [[ "$filename"  =~  .*.sh$ ]]   && echo true  ||  echo  false
    false
    [root@centos7 ~]# filename=f1.shshshs;  [[ "$filename"  =~  .*.sh ]]   && echo true  ||  echo  false
    true
    [root@centos7 ~]# filename=f1.shshshs;  [[ "$filename"  =~  .*.sh$ ]]   && echo true  ||  echo  false
    false
    [root@centos7 ~]# filename=f1.shshshs;  [[ "$filename"  =~  .sh$ ]]   && echo true  ||  echo  false
    false
    [root@centos7 ~]# filename=f1.shshsh;  [[ "$filename"  =~  .sh$ ]]   && echo true  ||  echo  false
    false
    [root@centos7 ~]# filename=f1.sh;  [[ "$filename"  =~  .sh$ ]]   && echo true  ||  echo  false
    true
    [root@centos7 ~]# filename=f1.sh;  [[ "$filename"  =~  .sh$ ]]   && echo true  ||  echo  false     
    #不管后缀前面的是什么,这种写法也可以 true [root@centos7 ~]# filename=f1.sh; [[ "$filename" =~ ".sh$" ]] && echo true || echo false
    #在正则表达式是不能加引号的 false [root@centos7 ~]# filename=f1.sh; [ "$filename" =~ ".sh$" ] && echo true || echo false
    #在正则表达式是不能加引号的 -bash: [: =~: binary operator expected false [root@centos7 ~]# filename=f1.sh; [ "$filename" =~ ".sh$" ] && echo true || echo false
    #在正则表达式是不能加引号的,单中括号是不支持=~和正则表达式的, -bash: [: =~: binary operator expected false [root@centos7 ~]# var="abc*"; [[ "$var" == "abc*" ]] && echo true || echo false true [root@centos7 ~]# var="abc*"; [[ "$var" == abc* ]] && echo true || echo false true [root@centos7 ~]# #==不支持正则表达式,而是精确匹配,双引号起到了引用的作用,不是引号本身,加不加引号效果一样。 [root@centos7 ~]# var="abcdefgh"; [[ "$var" == abc* ]] && echo true || echo false true [root@centos7 ~]# #这里的*表示的通配符,表示正则表达式。注意如果是精确匹配==就不要用双中括号了,这样更不容易搞混。

    判断IP地址是否是正确的,匹配IP地址

    注意要锚定行首行尾

    [root@centos7 ~]# ip="192.168.36.1";[[  $ip =~    <(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])>    ]]    &&   echo  $ip  is  correct   ||   echo  $ip  is incorrect
    192.168.36.1 is incorrect
    [root@centos7 ~]# ip="192.168.36.1";[[  $ip =~    ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$    ]]    &&   echo  $ip  is  correct   ||   echo  $ip  is incorrect
    192.168.36.1 is correct

    变量值加不加引号没啥区别

    [root@centos7 ~]# ip=192.168.36.1;[[  $ip =~    ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$    ]]   &&   echo  $ip  is  correct   ||   echo  $ip  is incorrect
    192.168.36.1 is correct

    判断一个变量是否是纯数字

    涉及到正则表达式。*表示包括0次,+表示至少一次

    [root@centos7 ~]# unset var;  [[ "$var" =~  ^[0-9]*$ ]]   &&  echo  true  ||  echo false
    true
    [root@centos7 ~]# unset var;  [[ "$var" =~  ^[0-9]+$ ]]   &&  echo  true  ||  echo false
    false
    [root@centos7 ~]#  var=123456;  [[ "$var" =~  ^[0-9]+$ ]]   &&  echo  true  ||  echo false
    true
    [root@centos7 ~]#  var=a23456;  [[ "$var" =~  ^[0-9]+$ ]]   &&  echo  true  ||  echo false
    false
    [root@centos7 ~]#  var=023456;  [[ "$var" =~  ^[0-9]+$ ]]   &&  echo  true  ||  echo false
    true
    [root@centos7 ~]#  var=023450;  [[ "$var" =~  ^[0-9]+$ ]]   &&  echo  true  ||  echo false
    true
    [root@centos7 ~]#  var=0;  [[ "$var" =~  ^[0-9]+$ ]]   &&  echo  true  ||  echo false
    true
    [root@centos7 ~]#  var=0a;  [[ "$var" =~  ^[0-9]+$ ]]   &&  echo  true  ||  echo false
    false

    判断是正整数,不括号0

    
    [root@centos7 ~]#  var=0;  [[ "$var" =~  ^[1-9][0-9]*$ ]]   &&  echo  true  ||  echo false  
    #*表示前面的字符重复0次或者任意次 false [root@centos7 ~]# var=1; [[ "$var" =~ ^[1-9][0-9]*$ ]] && echo true || echo false
    #*表示前面的字符重复0次或者任意次 true [root@centos7 ~]# var=123455670; [[ "$var" =~ ^[1-9][0-9]*$ ]] && echo true || echo false
    #*表示前面的字符重复0次或者任意次 true [root@centos7 ~]# var=10000002345567; [[ "$var" =~ ^[1-9][0-9]*$ ]] && echo true || echo false
    #*表示前面的字符重复0次或者任意次 true [root@centos7 ~]# var=010000002345567; [[ "$var" =~ ^[1-9][0-9]*$ ]] && echo true || echo false
    #*表示前面的字符重复0次或者任意次 false [root@centos7 ~]# var=010000002345567; [[ "$var" =~ ^0*[1-9][0-9]*$ ]] && echo true || echo false
    #*表示前面的字符重复0次或者任意次 true [root@centos7 ~]# #0*表示的0可以没有,也可以出现好几个。[1-9]表示中间必须是1到9,最后的数是重复0到9任意的数0次及以上。 [root@centos7 ~]# var=000000010000002345567; [[ "$var" =~ ^0*[1-9][0-9]*$ ]] && echo true || echo false
    #*表示前面的字符重复0次或者任意次 true [root@centos7 ~]# var=0000007; [[ "$var" =~ ^0*[1-9][0-9]*$ ]] && echo true || echo false
    #*表示前面的字符重复0次或者任意次 true

    示例——匹配手机号

    注意手机号第二位现在没有1,2,{9}表示重复前面的数字9次

    [root@centos7 ~]# mobile=12345670000 ;[[ "$mobile" =~ ^1[3456789][0-9]{9}$  ]] && echo true || echo false 
    false
    [root@centos7 ~]# mobile=13345670000 ;[[ "$mobile" =~ ^1[3456789][0-9]{9}$  ]] && echo true || echo false 
    true


    作者:wang618
    出处:https://www.cnblogs.com/wang618/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。

  • 相关阅读:
    2019-9-2-一个好的程序员
    2019-9-2-一个好的程序员
    2018-2-13-wpf-GifBitmapDecoder-解析-gif-格式
    2018-2-13-wpf-GifBitmapDecoder-解析-gif-格式
    2019-5-31-SharpDx-进入全屏模式
    2019-5-31-SharpDx-进入全屏模式
    2019-8-31-dotnet-删除只读文件
    2019-8-31-dotnet-删除只读文件
    PHP mysqli_real_connect() 函数
    PHP mysqli_query() 函数
  • 原文地址:https://www.cnblogs.com/wang618/p/11037406.html
Copyright © 2020-2023  润新知