双方括号[[]]优于Bash中的单方括号[]吗?

一位同事最近在一篇代码审查中声称, [[ ]]结构比结构中的[ ]要优于[ ]

if [ "`id -nu`" = "$someuser" ] ; then 
     echo "I love you madly, $someuser"
fi

他无法提供理由。 有一个吗?


[[减少惊喜,通常更安全。 但它不可移植 - POSIX没有指定它的功能,只有一些shell支持它(除了bash,我听说ksh也支持它)。 例如,你可以做

[[ -e $b ]]

测试文件是否存在。 但是对于[ ,你必须引用$b ,因为它分裂了参数并扩展了诸如"a*" (其中[[从字面上理解])。 这也与[可以是外部程序并像其他程序一样接收其参数一样(虽然它也可以是内置的,但是它仍然没有这种特殊的处理)。

[[也有其他一些很好的功能,比如正则表达式与=~匹配,以及类似C语言的运算符。 这里有一个很好的网页:测试, [[[ ? 和Bash测试


[[ ]]具有更多特性 - 我建议你参考高级Bash脚本指南了解更多信息,特别是第7章中的扩展测试命令部分。测试。

顺便提一下,作为指导性说明, [[ ]]是在ksh88(Korn shell的1988版[[ ]]中引入的。


行为差异

首先,我们来分析两者之间的行为差​​异。 在Bash 4.3.11中测试。

  • POSIX vs Bash扩展:

  • [是POSIX
  • [[是Bash扩展名
  • 常规命令vs魔术

  • [只是一个带有奇怪名字的常规命令。

    ]只是[阻止进一步论证被使用的论据]

    Ubuntu 16.04在/usr/bin/[ coreutils提供的实际上有一个可执行文件,但bash内置版本优先。

    Bash解析命令的方式没有任何改变。

    特别是, <是重定向, &&|| 连接多个命令, ( )生成子壳,除非被转义,并且字扩展像往常一样发生。

  • [[ X ]]是一个单独的构造,它可以神奇地解析X <&&||()分别处理,分词规则不同。

    还有更多的差异,如==~

  • 在Bashese中: [是一个内置命令, [[是关键字:https://askubuntu.com/questions/445749/whats-the-difference-between-shell-builtin-and-shell-keyword

  • <

  • [[ a < b ]] :词典对比
  • [ a < b ] :同上。 所需或否则重定向像任何其他命令一样。 Bash扩展。
  • 我找不到POSIX的替代方案,请参阅:如何测试小于或等于的字符串?
  • &&||

  • [[ a = a && b = b ]] :真,逻辑和
  • [ a = a && b = b ] :语法错误, &&解析为AND命令分隔符cmd1 && cmd2
  • [ a = a -ab = b ] :相当于POSIX,但不推荐使用
  • [ a = a ] && [ b = b ] :POSIX推荐
  • (

  • [[ (a = a || a = b) && a = b ]] :假
  • [ ( a = a ) ] :语法错误, ()被解释为一个子shell
  • [ ( a = a -oa = b ) -aa = b ] :等效,但()被POSIX弃用
  • ([ a = a ] || [ a = b ]) && [ a = b ] POSIX建议
  • 分词

  • x='a b'; [[ $x = 'ab' ]] x='a b'; [[ $x = 'ab' ]] :真,不需要引号
  • x='a b'; [ $x = 'ab' ] x='a b'; [ $x = 'ab' ] :语法错误,展开为[ ab = 'ab' ]
  • x='a b'; [ "$x" = 'ab' ] x='a b'; [ "$x" = 'ab' ] :等效
  • =

  • [[ ab = a? ]] [[ ab = a? ]] :真,因为它确实符合模式匹配( * ? [是魔术)。 不会扩展到当前目录中的文件。
  • [ ab = a? ] [ ab = a? ]a? glob扩展。 所以根据当前目录中的文件可能是真或假。
  • [ ab = a? ] [ ab = a? ] :false,不是glob扩展
  • ===[[[中是相同的,但==是Bash扩展。
  • printf 'ab' | grep -Eq 'a.' :相当于POSIX ERE
  • [[ ab =~ 'ab?' ]] [[ ab =~ 'ab?' ]] :假,失去了魔术''
  • [[ ab? =~ 'ab?' ]] [[ ab? =~ 'ab?' ]] :true
  • =~

  • [[ ab =~ ab? ]] [[ ab =~ ab? ]] :true,POSIX扩展正则表达式匹配, ? 不会扩大
  • [ a =~ a ] :语法错误
  • printf 'ab' | grep -Eq 'ab?' :相当于POSIX
  • 建议

    我更喜欢总是使用[]

    对于我见过的每个[[ ]]结构都有POSIX等价物。

    如果你使用[[ ]]你:

  • 失去可移植性
  • 迫使读者了解另一个bash扩展的复杂性。 [只是一个带有奇怪名称的常规命令,不涉及特殊的语义。
  • 链接地址: http://www.djcxy.com/p/2885.html

    上一篇: Is double square brackets [[ ]] preferable over single square brackets [ ] in Bash?

    下一篇: In Node.js, how do I "include" functions from my other files?