• 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 都不支持 >= 和 <=。
对于整型数字的比较,建议使用 (()),(()) 支持各种运算符,写法也符合数学规则,用起来更加方便

最新文章

  1. ThinkPHP 3.2.3(一)基础
  2. 为opencv贡献代码
  3. IIS发布WCF遇到的问题总结
  4. 利用Gson和SharePreference存储结构化数据
  5. 登陆mysql时提示异常的解决方法
  6. 修改SVN账户密码的方法
  7. 在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序(老罗学习笔记3)
  8. &lt;a href=&quot;javascript:void(0);&quot; id=&#39;test&#39; onclick=&quot;javascript:alert(&#39;即将上线,敬请期待!&#39;);&quot;&gt;&lt;em class=&quot;rmwd&quot;&gt;&lt;/em&gt;征稿平台&lt;/a&gt;
  9. Linq 两个集合模糊查询
  10. More is better--hdu1856(并查集)
  11. 关于C++异常机制的笔记(SEH, try-catch)
  12. [Usaco2007 Jan]Running贝茜的晨练计划[一般DP]
  13. ioc和aop
  14. Ball HDU - 4811
  15. 你不知道的JavaScript--Item17 循环与prototype最后的几点小tips
  16. 转 Redis 总结精讲 看一篇成高手系统-4
  17. ELK大流量日志分析系统搭建
  18. 5、Qt Project之键盘数据监控
  19. Module not found: Error: Can't resolve 'XXX' in 'XXXX'
  20. 公共表达式消除(UVa 12219)

热门文章

  1. JQuery Ajax 请求参数 List 集合处理
  2. Centos7挂载windows共享目录
  3. Docker的镜像理解以及容器的备份、恢复和迁移操作
  4. Spring Cloud Alibaba系列之分布式服务组件Dubbo
  5. redis主从架构宕机问题手动解决
  6. Oracle的Rman差异增量备份
  7. Halide视觉神经网络优化
  8. 神经网络AI加速器技术
  9. 全卷积网络Fully Convolutional Networks (FCN)实战
  10. Docker与k8s的恩怨情仇(一)—成为PaaS前浪的Cloud Foundry