网站地图    收藏   

主页 > 系统 > linux系统 >

linux中shell test 条件表达式说明

来源:未知    时间:2015-05-07 11:40 作者:xxadmin 阅读:

[导读] shell test 条件表达式对于很多的开发者来讲都是不很理解了,下文我来为各位介绍一些关于linux中shell test 条件表达式的说明与例子. 条件表达式(CONDITIONAL EXPRESSIONS) 条件表达式用于 [[ 复合...

shell test 条件表达式对于很多的开发者来讲都是不很理解了,下文我来为各位介绍一些关于linux中shell test 条件表达式的说明与例子.

条件表达式("CONDITIONAL EXPRESSIONS")

条件表达式用于 [[ 复合命令以及内建命令 test 和 [ 中,用来测试文件属性,进行字符串和算术比较,表达式使用下面的单目或二进制操作构造,如果某操作的任何 file 参数的形式是.

文件符号:在info bash里的第“6.4 Bash Conditional Expressions”节里开头有一句话说明了shell条件判断的二个机制:

Conditional expressions are used by the `[[' compound command and the

`test' and `[' builtin commands.

机制一:内置(builtin)的函数test(运算符[]),此部分完整的说明,可查看“4.1 Bourne Shell Builtins”

机制二:[[]],条件结构关健字,具体可查看“3.2.4.2 Conditional Constructs”

test跟[]是一回事,只不过一个以函数的形式,一个以成对操作符的形式出现,test包含6.4节条件表达式的表达形式,是函数就有参数,test对1、2、3.。。6等多个参数的判断分别进行定义,而[[]],大部分的功能跟[]是一样的,可以简单理解成[]的扩展,但对于参数的判断定义上,比test有更完整的定义,不容易出现[]中的错误,比如在-eq比较的右操作符中,[]要求右操作符不为空,否则报错,返回2,而[[]]则不会.

  1. [root@localhost tmp]# [ 1 -eq  $a ]      
  2. + '[' 1 -eq ']' 
  3. -bash: [: 1: unary operator expected 
  4. [root@localhost tmp]# echo $?       
  5. + echo 2 
  6. [root@localhost tmp]# [[ 1 -eq  $a ]] 
  7. + [[ 1 -eq '' ]] 
  8. [root@localhost tmp]# echo $?         
  9. + echo 1 

这也是很多程序员喜欢用[[]]的原因,不容易出错,test的表达能力,[[]]扩展了二个功能.

1:pattern match,通配符匹配,采用双等号“==”

2:regex match,正则匹配,采用“=~”运算符号

首先说明下通配符匹配:先说明一下[]里的==运算,[]也包括==比较,用于字符串相等比较,同样,==号在这里也不允许右操作符为空,否则报错.

  1. [root@localhost tmp]# [ "abc" == $a  ]   
  2. + '[' abc == ']' 
  3. -bash: [: abc: unary operator expected 

解决办法是加个引号:

  1. [root@localhost tmp]# [ "abc" == "$a"  ] 
  2. + '[' abc == '' ']' 

而[[]]里的==,在3.2.4.2 里有介绍:

  1. When the `==' and `!=' operators are used, the string to the right 
  2.      of the operator is considered a pattern and matched according to 
  3.      the rules described below in *Note Pattern Matching::。。。 
  4. Any part of the pattern may be quoted 
  5.      to force it to be matched as a string. 

这一段说明至少要注意二点:

1:[[]]里的==运算符,把所有右操作符都看做是一个pattern,==实际上不只是简单字符串比较,而是pattern match,即通配符匹配,具体的规则可以参考

3.5.8.1 Pattern Matching

2:最后一句:引号可以直接定义字符串,在3.5.8.1里也有一句话:The special pattern

characters must be quoted if they are to be matched literally.

即:pattern特殊字符为字符在引号里取消特殊定义

这也就能解释下边的二个例子的差别了:

  1. [root@localhost tmp]# set -x 
  2. + set -x 
  3. [root@localhost tmp]# [[ abc == a*c ]] 
  4. + [[ abc == a*c ]] 
  5. [root@localhost tmp]# echo $?          
  6. + echo 0 
  7. [root@localhost tmp]# [[ abc == "a*c" ]] 
  8. + [[ abc == /a/*/c ]] 
  9. [root@localhost tmp]# echo $?            
  10. + echo 1 

另外需要留意下:在[[里,文档中提到:

  1. Word splitting and filename expansion are not 
  2.      performed on the words between the `[[' and `]]'; tilde expansion, 
  3.      parameter and variable expansion, arithmetic expansion, command 
  4.      substitution, process substitution, and quote removal are 
  5.      performed. 

也就是说,在[[里,不进行bash命令解析中的“文字分割Word splitting ” 和 “文件名扩展filename expansion ”但还是进行了 “~符号扩展,参数和变量扩展,算术扩展,命令替换,进程替换,引号去除”,所以不必担心上边例子中,a*b是否会扩展成目录下的文件名.

至于=~正则匹配,就没有什么特别是的了,右操作数直接定义成一个正则式子即是,这里正则的引号可用可不用(不能用/),因为在 “quote removal ”环节,对非扩展出来的引号做了去除处理,实际上有加引号与不加引号是一样的结果.

  1. [root@localhost tmp]# [[ abc =~ 'ab*c' ]]   
  2. + [[ abc =~ ab*c ]] 
  3. [root@localhost tmp]# echo $?             
  4. + echo 0 
  5. [root@localhost tmp]# [[ abc =~ "ab*c" ]]   
  6. + [[ abc =~ ab*c ]] 
  7. [root@localhost tmp]# echo $? 
  8. + echo 0 
  9. [root@localhost tmp]# [[ abc =~ ab*c ]]   
  10. + [[ abc =~ ab*c ]] 
  11. [root@localhost tmp]# echo $?           
  12. + echo 0  --phpfensi.com 
  13. [root@localhost tmp]# [[ abc =~ /ab*c/ ]] 
  14. + [[ abc =~ /ab*c/ ]] 
  15. [root@localhost tmp]# echo $?             
  16. + echo 1 

自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习

京ICP备14009008号-1@版权所有www.zixuephp.com

网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com

添加评论