Bash中单方括号和双方括号的区别
  我正在阅读关于if bash示例,但是一些示例用单个方括号写入: 
if [ -f $param ]
then
  #...
fi
其他与双方括号:
if [[ $? -ne 0 ]]
then
    start looking for errors in yourlog
fi
有什么不同?
  Single []是符合posix外壳的条件测试。 
  Double [[]]是标准[]的扩展,受bash和其他shell支持(例如zsh,ksh)。  它们支持额外的操作(以及标准的posix操作)。  例如: ||  而不是-o和正则表达式匹配=~ 。  关于条件结构的bash手册部分可以找到更多的差异列表。 
  每当你希望你的脚本跨shell可移植时使用[] 。  如果您希望条件表达式不受[]支持,并且不需要可移植,请使用[[]] 。 
行为差异
在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扩展。   &&和|| 
[[ 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等价物。 
  如果你使用[[ ]]你: 
[只是一个带有奇怪名称的常规命令,不涉及特殊的语义。   在条件测试(即[...])的单个括号内,所有shell支持一些运算符(如single = ),而某些较旧的shell不支持使用operator == 。 
  在条件测试的双括号内(即[[...]]),在旧shell或新shell中使用=或==没有区别。 
编辑:我还应该注意到:在bash中,如果可能,总是使用双括号[[...]],因为它比单个括号更安全。 我会用下面的例子来说明为什么:
if [ $var == "hello" ]; then
如果$ var恰好为null / empty,那么这就是脚本所见:
if [ == "hello" ]; then
  这会破坏你的脚本。  解决方案是使用双括号,或者始终记住在变量周围加上引号( "$var" )。  双括号是更好的防守编码练习。 
上一篇: Difference between single and double square brackets in Bash
下一篇: Difference in Bash between IF statements with parenthesis and square brackets
