【Linux】 shell if的[]和[[]]区别
创始人
2024-05-28 15:14:33
0

文章目录

  • []和test
  • []和[[]]区别
  • 总结
  • 参考

[]和test

Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试

test常用于 if ,作为判断条件,if test等价于 if [ ],因此,test和[] 内的内容完全可以直接互换!都支持

[]的语法可以参见 【Linux】shell中运算符(expr整数、字符串) 中的示例
test 语法参见 Shell test 命令

当然test也可以单独执行,如果当前目录存在hello.sh文件,则会获得返回值 0:

[root@linuxforliuhj test]# test -f hello.sh 
[root@linuxforliuhj test]# echo $?          
0

上面命令等价于下面语法:

[root@linuxforliuhj test]# [ -f hello.sh ]
[root@linuxforliuhj test]# echo $?          
0

因此 [] 就是一个内置命令,有返回值,而不是一个符号,[[]] 就是一个符号,不能单独存在,依赖 if

执行结果0 表示 true ,1 表示false

[]和[[]]区别

[] 或 [[]] 中,$a 表示变量a,如果没有$符号,默认为字符串,即 [[ a = b ]]等价于 [[ ‘a’ = ‘b’ ]]

  • 先有[] 语法,并内置于linux系统,后来才有 [[]] ,起初不是所有的都支持 [[]] ,当然后来基本上都支持了

  • [] 语法 都可以由 [[]] 替代,并且后者功能更丰富。二者大部分语法都相同,但是默认情况下 [] 识别的运算符比较少,需要使用转义字符等,下面会详解列出不同之处。

  • 二者都建议在表达式和括号自身使用空格 ,避免出错 if [[ $1 != "start" && $1 != "stop" ]],加空格一定不会报错,不加可能会报错

  • 当目标是数字类型时,二者都可以使用 -eq进行数字比较
    当使用-eq,并且类型被错误的赋值为非数字时,会提示错误,这样便于检查语法错误。

    示例:

    a=10
    b=20if [ $a -eq $b ]
    thenecho "$a -eq $b : a 等于 b"
    elseecho "$a -eq $b: a 不等于 b"
    fi
    
  • 当目标是数字类型时,都支持>、>=等 数字比较符,但是都 不建议使用,建议使用 -eq语法
    但是要注意的是 [] 需要增加转义字符,原因是[]默认 不识别特殊字符,而[[]] 天生支持

    a=10
    b=20
    if [ $a < $b ]         //单中括号执行报错,不识别 <号
    thenecho "$a < $b : a < b"
    elseecho "$a > $b: a > b"
    fi	if [[ $a < $b ]]	 //双中括号执行成功
    thenecho "$a < $b : a < b"
    elseecho "$a > $b: a > b"
    fi	if [ $a \< $b ]    //转义字符执行成功
    thenecho "$a < $b : a < b"
    elseecho "$a > $b: a > b"
    fi	
  • 都可以使用= 、!=进行字符串比较
    需要注意的是,当字符串类型且有空格时,[]需要对字符串加引号,而[[]] 可加可不加

    #可以在终端命令行直接输入命令,分号是多条命令的分割符x='a b'; [ $x = 'a b' ]   //当字符串变量的值含有空格时,需要小心,执行会报错  [: too many arguments 错误,原因是把空格当做分割符了
    x='a b'; [ "$x" = 'a b' ]  //添加引号后,执行成功
    x='a b'; [[ $x = 'a b' ]]  //天生就可以执行成功
    

    当字符串类型且含有特殊字符,例如*号时,[]会报错,而[[]] 不会

    x='*'; [ $x = 'a b' ]  // bash: [: too many arguments
    x='*'; [[ $x = 'a b' ]]  // 执行成功
    
  • 在逻辑表达式语法稍有不同,[] 使用 -a、-o 分别表示与、或 关系 ,[[]]使用 &&、 ||表示与 、或关系

    单中括号示例:

    if [ $a -lt 100 -a $b -gt 15 ]
    thenecho "$a 小于 100 且 $b 大于 15 : 返回 true"
    elseecho "$a 小于 100 且 $b 大于 15 : 返回 false"
    fi
    

    双中括号示例:

    [[ a = a && b = b ]]
    

    单中括号不支持 &&语法,即使添加转义字符也不行,可以再外层使用 && :

     [ a = a && b = b ]    //错误[ a = a ] && [ b = b ]  //可以改造成这样,外部通过 &`在这里插入代码片`& 进行连接
    
  • 逻辑运算符的优先级
    优先级顺序 按照 : ()逻辑 > && > || ,并且单[] 不识别 小括号(),除非加转义字符

    unset a;unset b;  //清除a b 变量,防止影响执行结果[[ (a = a || a = b) && a = b ]];echo $? //注意是双中括号,最终结果为1  ,false ,先计算(a = a || a = b) 得到结果true ,然后再计算 true &&  a = b[[ a = a || a = b && a = b ]];echo $? // 注意是双中括号,最终结果为0  ,true,先计算右边  a = b && a = b,得到false,然后计算 a=a || false[ ( a = a ) ]  //报错,bash: syntax error near unexpected token 'a',即单括号不识别括号
    [ \( a = a -o a = b \) -a a = b ]   //没有语法错误
    
  • [[]]支持字符串模糊匹配,而[]不支持

    注意

    • 右侧不加引号时,支持通配符,左边是字符串,顺序不能颠倒 ;要想屏蔽通配符,需要加 转义字符;

    • 如果右侧是带引号的,此时就是普通字符串

    • * 可以使用星号代替零个、单个或多个字符;

    • ? 问号代替一个字符,必须有一个

    当是=号时,通配符表示是否以满足xxx条件

    [[ ab = a? ]]; echo $? //打印 0 true,因为 ?被当做通配符
    [[ a? = ab ]]; echo $?   //打印 1 false,颠倒了通配符因为失效了,在左侧就是普通字符串,等价于  [[ 'a?' = 'ab' ]]; echo $?
    [[ ab = a\? ]]; echo $? //打印	1	 false,因为加了转义字符,右侧通配符就是字符串了[[ ab =~ 'ab?' ]]; echo $? //打印 1 false ,因为加了引号,就是普通字符串
    

    当然通配符也可以用在前面:

    [[ ab = ?b ]];echo $?   //打印 0  true
    

    并且特别要注意的是,[] 中右侧的?匹配符号会被当做当前目录下的文件名称进行匹配,而不是字符串匹配了;
    *匹配符直接报错!前文得知,不管在左侧当做普通字符串,也报错
    因此建议禁用 通配符

    rm -f ab;touch ab;[ ab = a? ]; echo $?  # 打印 0 true  ,此时语法等价于 “是否当前目录存在ab这个文件,并且以a开头 ?”  比较别扭,也就是说 ab不再是字符串,而是当前目录的文件名称
    rm -f ab;[ ab = a? ]; echo $?  # 打印 1 falserm -f ab;touch ab;[ ab = a* ]; echo $?   # *号匹配符直接报错,
    
  • [[]]支持=~字符串模糊匹配,而[]不支持

    上一小节是用=进行判断,也可以用=~进行模糊判断,表示不满足条件,注意与!=进行区别:

    [[ ab =~ ab? ]]  ; echo $?   # 打印 0 true
    

    而[] 压根不支持=~,直接报错:

    [ a =~ a ] #  报错  bash: [: =~: binary operator expected

总结

尽量不用[],建议使用 [[]]

参考

linux shell if的[]和[[]]
[What is the difference between the Bash operators [[ vs vs ( vs ((?

相关内容

热门资讯

名人的英文作文(精彩3篇) 名人的英文作文 篇一Celebrities: The Good, the Bad, and the ...
英语作业作文(实用5篇) 英语作业作文 篇一:The Importance of Learning EnglishIn tod...
贪婪的猴子高考英语作文【优质... 贪婪的猴子高考英语作文 篇一Title: The Greedy MonkeyOnce upon a ...
初中英语作文:最后一天 Th... 初中英语作文:最后一天 The Last Day 篇一The Last DayToday is th...
描写感恩节的英语作文【实用6... 描写感恩节的英语作文 篇一Thanksgiving Day - A Time for Gratitu...
烧烤的小学英语作文【精简3篇... Barbecue FunBarbecue is a popular outdoor activity...
介绍春天的英语作文带翻译(精... 介绍春天的英语作文带翻译 篇一Title: The Beauty of SpringSpring i...
初二英语作文 关于初二英语作文(通用22篇)  在平时的'学习、工作或生活中,大家都不可避免地要接触到作文吧,作文...
初中英语保护环境句子【通用3... 初中英语保护环境句子 篇一The Importance of Protecting the Envi...
代沟的英语作文【最新3篇】 代沟的英语作文 篇一:Understanding the Generation GapIn toda...
英语小短文带翻译(推荐3篇) 篇一:The Benefits of Learning a Second Language 学习第二...
体育活动英语作文(推荐3篇) 篇一:体育活动英语作文Sports and Physical ActivitySports and ...
“愚人节”用英语怎么说【实用... “愚人节”用英语怎么说 篇一April Fools' DayApril Fools' Day, al...
帮助他人的英语作文【通用6篇... 帮助他人的英语作文 篇一Title: The Power of Helping OthersIntr...
高考英语满分范文山东(通用6... 高考英语满分范文山东 篇一A Trip to Mount TaiLast summer, I had...
美好生活 英语作文【实用3篇... 美好生活篇一:追求幸福的美好生活In the pursuit of a happy life, pe...
家乡的英语作文【优秀6篇】 家乡的英语作文 篇一A Glimpse into My HometownMy hometown is...
我的学校英语作文【精彩6篇】 我的学校英语作文 篇一:美丽的校园我所就读的学校是一所位于郊区的小学,校园虽然不大,但却充满了美丽和...
我的老师英语作文(推荐6篇) 我的老师英语作文 篇一我的英语老师是一位非常优秀的教师,她给我们上的每一堂课都充满了活力和乐趣。她是...
英文请假条【推荐6篇】 英文请假条 篇一Subject: Request for Leave of AbsenceDear ...