zoukankan      html  css  js  c++  java
  • 10 shell test命令

    • 0.test命令的用法
    • 1.与数值比较相关的test选项
    • 2.与字符串判断相关的 test 选项
    • 3.与文件检测相关的test选项
    • 4.与逻辑运算相关的test选项
    • 5.注意点与总结
      • 1.test中变量用双引号包围起来
      • 2.总结

    test 是 Shell 内置命令,用来检测某个条件是否成立。test 通常和 if 语句一起使用,并且大部分 if 语句都依赖 test。

    test 命令有很多选项,可以进行数值、字符串和文件三个方面的检测。

    0.test命令的用法

    用法注意点 
    用法1 test expression   两种用法是等价的,当 test 判断 expression 成立时,退出状态为 0,否则为非 0 值。
    用法2 [ expression ] 注意[]expression之间的空格,这两个空格是必须的,否则会导致语法错误

    1.与数值比较相关的test选项

    注意,test 只能用来比较整数,小数相关的比较还得依赖 bc 命令。

    选 项
    作 用
    num1 -eq num2 判断 num1 是否和 num2 相等。
    num1 -ne num2 判断 num1 是否和 num2 不相等。
    num1 -gt num2 判断 num1 是否大于 num2 。
    num1 -lt num2 判断 num1 是否小于 num2。
    num1 -ge num2 判断 num1 是否大于等于 num2。
    num1 -le num2 判断 num1 是否小于等于 num2。
    使用(())命令的脚本
    使用test命令的脚本
    运行结果
    注意点
    1. #!/bin/bash
    2. read -p 'please input num1: ' num1
    3. read -p 'please input num2: ' num2
    4. if (($num1==$num2))
    5. then
    6. echo 'the num is equal'
    7. elif ((num1>num2))
    8. then
    9. echo 'the num1 is large than num2'
    10. else
    11. echo 'the num1 is small num2'
    12. fi
    1. #!/bin/bash
    2. read -p 'please input num1: ' num1
    3. read -p 'please input num2: ' num2
    4. if test $num1 -eq $num2
    5. then
    6. echo 'the num is equal'
    7. elif [ $num1 -gt $num2 ]
    8. then
    9. echo 'the num1 is large than num2'
    10. else
    11. echo 'the num1 is small num2'
    12. fi

    第一次执行

    1. please input num1: 10
    2. please input num2: 10
    3. the num is equal

    第二次执行

    1. please input num1: 4
    2. please input num2: 6
    3. the num1 is small num2

    1.test 命令中的变量还是需要加$

    2.(())中的变量可以加也可以不加$

    3.test中的比较两数值的大小用的是-eq/-gt/-lt等,(())中用的是符号>/</==等

    4.[]命令中表达式前后的空格不要忘记!!

    2.与字符串判断相关的 test 选项

    选 项
    作 用
    -z str 判断字符串 str 是否为空
    -n str 判断宇符串 str 是否为非空
    str1 = str2
    str1 == str2
    ===是等价的,都用来判断 str1 是否和 str2 相等。
    str1 != str2 判断 str1 是否和 str2 不相等。
    str1 > str2 判断 str1 是否大于 str2。>>的转义字符,这样写是为了防止>被误认为成重定向运算符。
    str1 < str2 判断 str1 是否小于 str2。同样,<也是转义字符。

    注意,==、>、< 在大部分编程语言中都用来比较数字,而在 Shell 中,它们只能用来比较字符串,不能比较数字,这是非常奇葩的。
    其次,不管是比较数字还是字符串,Shell 都不支持 >= 和 <= 运算符,切记。

    Shell test 字符串比较举例:

    脚本
    结果
    注意点
    1. #!/bin/bash
    2. read -p 'input str1: ' str1
    3. read -p 'input str2: ' str2
    4. if [ -z "$str1" ]||[ -z "$str2" ]
    5. then echo 'the strings should not be empty'
    6. elif [ $str1 = $str2 ]
    7. then echo 'str1=str2'
    8. elif [ $str1 > $str2 ]
    9. then echo 'str1 > str2'
    10. elif [ $str1 < $str2 ]
    11. then echo 'str1<str2'
    12. fi
    1. input str1: aa
    2. input str2: 
    3. the strings should not be empty
    1. input str1: aa
    2. input str2: bb
    3. str1<str2
    1. input str1: aa
    2. input str2: aa
    3. str1=str2
    1. input str1: bb
    2. input str2: a
    3. str1 > str2

    1.判断字符串为空时将变量 $str1 和 $str2 都被双引号包围起来,这样做是为了防止 $str1 或者 $str2 是空字符串时出现错误

    2.比较两个字符串时,除了[]中表达式的前后需要空格还要注意str1=str2时,=前后也需要空格!!

    3.与文件检测相关的test选项

    文件类型判断
    选 项作 用
    -b filename 判断文件是否存在,并且是否为块设备文件。
    -c filename 判断文件是否存在,并且是否为字符设备文件。
    -d filename 判断文件是否存在,并且是否为目录文件。
    -e filename 判断文件是否存在。
    -f filename 判断文件是否存在,井且是否为普通文件。
    -L filename 判断文件是否存在,并且是否为符号链接文件。
    -p filename 判断文件是否存在,并且是否为管道文件。
    -s filename 判断文件是否存在,并且是否为非空。
    -S filename 判断该文件是否存在,并且是否为套接字文件。
    文件权限判断
    选 项作 用
    -r filename 判断文件是否存在,并且是否拥有读权限。
    -w filename 判断文件是否存在,并且是否拥有写权限。
    -x filename 判断文件是否存在,并且是否拥有执行权限。
    -u filename 判断文件是否存在,并且是否拥有 SUID 权限。
    -g filename 判断文件是否存在,并且是否拥有 SGID 权限。
    -k filename 判断该文件是否存在,并且是否拥有 SBIT 权限。
    文件比较
    选 项作 用
    filename1 -nt filename2 判断 filename1 的修改时间是否比 filename2 的
    filename -ot filename2 判断 filename1 的修改时间是否比 filename2 的
    filename1 -ef filename2 判断 filename1 是否和 filename2 的 inode 号一致,可以理解为两个文件是否为同一个文件。这个判断用于判断硬链接是很好的方法
    脚本
    结果
    注意点
    1. #!/bin/bash
    2. read -p 'input filename1: ' filename1
    3. read -p 'imput filename2: ' filename2
    4. if [ -z "$filename1" ]||[ -z "$filename2" ];#判断输入值是否为空
    5. then echo 'the input is  empty'
    6. elif [ ! -e "$filename1" ]||[ -e "$filename2" ];#判断输入文件是否存在,如果不存在提示并退出
    7. then echo 'please input exist file'
    8. exit 2
    9. elif [ -s "$filename1" ]||[ -s "$filename2" ];#判断输入文件是否为空,为空则提示退出
    10. then echo 'please input not empty file'
    11. exit 2
    12. elif [ -d "$filename1" ]||[ -d "$filename2" ];#判断输入文件是否为目录,是则提示退出
    13. then echo 'please input filename, not dir'
    14. exit 2
    15. elif [ $filename1 -nt $filename2 ];#判断文件新旧
    16. then echo 'file1 new file2'
    17. elif [ $filename1 -ot $filename2 ];#判断文件新旧
    18. then echo 'file1 old file2'
    19. elif [ $filename1 -ef $filename2 ];#判断文件是否相同
    20. then echo 'file1 equal file2'
    21. else
    22. echo 'some error'
    23. fi
    1. input filename1: aa
    2. imput filename2: 
    3. the input is empty
    1. input filename1: aa
    2. imput filename2: bb
    3. please input exist file
    1. touch aaa
    2. input filename1: aaa
    3. imput filename2: /data/1learn_linux/
    4. please input not empty file
    1. input filename1: /data/1learn_linux/
    2. imput filename2: /data/1learn_linux/learn_test_str.sh
    3. please input filename, not dir
    1. input filename1: /data/1learn_linux/learn_test_str.sh
    2. imput filename2: /data/1learn_linux/learn_test.sh
    3. file1 new file2
    1. input filename1: /data/1learn_linux/learn_test.sh
    2. imput filename2: /data/1learn_linux/learn_test_str.sh
    3. file1 old file2
    1. input filename1: /data/1learn_linux/learn_test.sh
    2. imput filename2: /data/1learn_linux/learn_test.sh
    3. file1 equal file2

    1.空格

    2.逻辑非要放在表达式前边,例如 [ ! -e "$filename1" ]

    -e "$filename1"代表的是文件存在的情况

    ! -e "$filename1"代表的是文件不存在时的情况

    4.与逻辑运算相关的test选项

    选 项
    作 用
    expression1 -a expression 逻辑与,表达式 expression1 和 expression2 都成立,最终的结果才是成立的。
    expression1 -o expression2 逻辑或,表达式 expression1 和 expression2 有一个成立,最终的结果就成立。
    !expression 逻辑非,对 expression 进行取反。


    改写上面的代码,使用逻辑运算选项:

    脚本
    结果
    注意点
    1. #!/bin/bash
    2. read -p 'input filename1: ' filename1
    3. read -p 'imput filename2: ' filename2
    4. if [ -z "$filename1" -o -z "$filename2" ];#判断输入值是否为空
    5. then echo 'the input is  empty'
    6. elif [ ! -e "$filename1" -o -e "$filename2" ];#判断输入文件是否存在,如果不存在提示并退出
    7. then echo 'please input exist file'
    8. exit 2
    9. else
    10.  echo 'files exist'
    11. fi
    1. input filename1: aa
    2. imput filename2: bb
    3. please input exist file
    1. input filename1: /data/1learn_linux/
    2. imput filename2: aa
    3. please input exist file
    1. input filename1: aa
    2. imput filename2: /data/1learn_linux/
    3. please input exist file
    1. input filename1: /data/1learn_linux/
    2. imput filename2: /data/1learn_linux/
    3. files exist

    1.逻辑非!与-o混用时,注意!只起作用于当前表达式,不是-o链接起来的整个表达式

    2.使用-o,将两个[]合为1个

    5.注意点与总结

    1.test中变量用双引号包围起来

    假设 test 命令对应的函数是 func(),使用test -z $str1命令时,会先将变量 $str1 替换成字符串:

    1. 如果 $str1 是一个正常的字符串,比如 abc123,那么替换后的效果就是test -z abc123,调用 func() 函数的形式就是func("-z abc123")。test 命令后面附带的所有选项和参数会被看成一个整体,并作为实参传递进函数。
    2. 如果 $str1 是一个空字符串,那么替换后的效果就是test -z ,调用 func() 函数的形式就是func("-z "),这就比较奇怪了,因为-z选项没有和参数成对出现,func() 在分析时就会出错。


    如果我们给 $str1 变量加上双引号,当 $str1 是空字符串时,test -z "$str1"就会被替换为test -z "",调用 func() 函数的形式就是func("-z """),很显然,-z选项后面跟的是一个空字符串("表示转义字符),这样 func() 在分析时就不会出错了。

    所以,当在 test 命令中使用变量时,强烈建议将变量用双引号""包围起来,这样能避免变量为空值时导致的很多奇葩问题。

    2.总结

    test 命令比较奇葩,>、<、== 只能用来比较字符串,不能用来比较数字,比较数字需要使用 -eq、-gt 等选项;不管是比较字符串还是数字,test 都不支持 >= 和 <=。
    对于整型数字的比较,建议使用 (()),(()) 支持各种运算符,写法也符合数学规则,用起来更加方便

  • 相关阅读:
    08-12 NOIP模拟测试18
    08-09 NOIP模拟测试15
    08-11 NOIP模拟测试17
    08-10 NOIP模拟测试16
    08-07 NOIP模拟测试14
    08-03 NOIP模拟测试12
    [SDOI2011]拦截导弹
    08-01 NOIP模拟测试11
    零散知识点
    07-29 NOIP模拟测试10
  • 原文地址:https://www.cnblogs.com/mianbaoshu/p/12069581.html
Copyright © 2011-2022 走看看